“add to set” returns a boolean in java - what abou

2019-06-16 05:34发布

问题:

In Java I like to use the Boolean value returned by an "add to the set" operation to test whether the element was already present in the set:

if (set.add("x")) {
   print "x was not yet in the set";
}

My question is, is there something as convenient in Python? I tried

 z = set()
 if (z.add(y)):
     print something

But it does not print anything. Am I missing something? Thx!

回答1:

In Python, the set.add() method does not return anything. You have to use the not in operator:

z = set()
if y not in z: # If the object is not in the list yet...
    print something
z.add(y)

If you really need to know whether the object was in the set before you added it, just store the boolean value:

z = set()
was_here = y not in z
z.add(y)
if was_here: # If the object was not in the list yet...
    print something

However, I think it is unlikely you need it.

This is a Python convention: when a method updates some object, it returns None. You can ignore this convention; also, there are methods "in the wild" that violate it. However, it is a common, recognized convention: I'd recommend to stick to it and have it in mind.



回答2:

Generally, Python tries to avoid using conditions with side-effects. That is, the condition should be just a test, and operations that change data should happen on their own.

I agree that it's sometimes convenient to use a side-effect in a condition, but no, in this case, you need to:

z = set()
if y not in z:
    z.add(y)
    print something

Personally I like the simple expressiveness of if y not in z:, even if it takes up one more line of code, and it's one less thing to mentally parse when reading the the code at a later date.



回答3:

As mentioned in the previous answers, the add method for Python sets does not return anything. By the way, this exact question was discussed on the Python mailing list: http://mail.python.org/pipermail/python-ideas/2009-February/002877.html.



回答4:

I guess, in Python is basically add y to your set if needed and doesn't return anything. You can test if y is already in z if you would like to know if the add will change anything.

Here some tests you can do in iPython :

In [2]: z = set()

In [3]: y = 4

In [4]: z.add(y)

In [5]: t = z.add(y)

In [6]: t

In [7]: print t
None


回答5:

For the built-in set type, add() always gives back None, but there is nothing to prevent you from using a "smarter" subclass:

class sset(set):
    """return True if on add if an object was really added (and not in yet)"""
    def add(self, val):
        if val in self:
            return True
        set.add(self, val)
        return False

This allows you to write:

s = sset()
if s.add('1'):
    print('try 1')
if s.add('1'):
    print('try 2')

and get try 2 printed when run.

This prevents repeated multiple lines of code like @brandizzi's which can easily contain inefficiencies:

z = set()
was_here = y not in z
z.add(y)
if was_here: # If the object was not in the list yet...
    print something

which is inefficient as y is added even if it is already in. It should be something like:

z = set()
was_here = y not in z
if not was_here:
    z.add(y)
else: # If the object was not in the list yet...
    print something

With sset() this can be reduced to:

z = sset()
if z.add(y): # If the object was not in the list yet...
    print something


标签: java python set