问题
Java's Set.add function will return a boolean value, which is true if the set did not already contain the specified element.
Python's Set.add does not have a return value.
Seems like in Python if I want to do the same thing, I have to check if it is in the set first and then add it if not.
Is there a simpler way to do that (preferably a one-liner)?
Ref:
https://docs.oracle.com/javase/7/docs/api/java/util/Set.html#add(E)
https://docs.python.org/2/library/sets.html#sets.Set
回答1:
If you want a one-liner, you could use or to add the element only if it is not already in the set (short-circuit evaluation), and not to inverse the returned value and at the same time coerce to bool, turning the None returned by add, if it is called, into True, and otherwise just inverting the result of the in check:
>>> s = set()
>>> not(42 in s or s.add(42))
True
>>> not(42 in s or s.add(42))
False
>>> s
set([42])
However, since that one-liner might not be very easy to grasp, and you have to write the value to be inserted twice, you should probably make it a function, and then it does not matter much how many lines it uses.
def in_or_add(s, x):
return not(x in s or s.add(x))
回答2:
No, Python's set implementation has no such method; as you noted you'll have to test for presence separately:
if obj not in setobj:
setobj.add(obj)
or, what I usually do:
if obj in setobj:
return # or break out of a loop, etc.
# handle the case where the set doesn't have the object yet.
You can always subclass the set type:
class SetWithPresenceCheck(set):
def add(self, value):
not_present = value not in self
super(SetWithPresenceCheck, self).add(value)
return not_present
Note that the real reason Set.add() returns a boolean is to make adding and testing an atomic operation; implementations of the interface can (optionally) make the method synchronised and let callers avoid race conditions. Python's built-in set doesn't make any thread-safety promises anyway.
回答3:
The union operator is much faster than add anyway.
>>> set_a = set('pqrs')
>>> set_b = ['t', 'u', 'v']
>>> set_a |= set(set_b)
>>> set_a
set(['p','q','r','s','t','u','v'])
回答4:
maybe with ternary conditional operator :
the_set.add(what_ever) or True if what_ever not in the_set else False
This will return False if what_ever was in the set, True if it wasn't
来源:https://stackoverflow.com/questions/38563245/pythons-equivalent-of-javas-set-add