To my understanding, adding elements to a set
does not return anything.
eg:
>>> s=set([1,2,3])
>>> s.add(1)
>>> b = s.add(1)
>>> b
>>> b = s.add(5)
>>> b
>>> print b
None
>>> b = s.add(5)
>>> print b
None
but I am confused how this function to remove duplicates of a list while preserving order works:
def f7(seq):
seen = set()
seen_add = seen.add
return [ x for x in seq if x not in seen and not seen_add(x)]
not seen_add(x) return true always irrespective of if I add duplicates or not.
The only real check is if x not in seen
, since if that fails, it will not perform not see_add(x)
.
Is my understanding here or am I missing something?
however, here, not seen_add(1)
return true if I add duplicate or a unique element.
This is puzzling, so is the not
here just do an empty check? but seen_add()
is not returning a set to do an empty
check. and why seen_add(2)
does not return anything but not seen_add(1)
returns the boolean True
>>> seen=set()
>>> seen_add=seen.add
>>> seen_add(1)
>>> seen
set([1])
>>> seen.add(2)
>>> seen
set([1, 2])
>>> not seen_add(1)
True
>>> not seen_add(4)
True
As you have discovered, seen_add(x)
always returns None
.
Now, not None
is True
:
>>> not None
True
This is explained in the documentation:
5.1. Truth Value Testing
Any object can be tested for truth value, for use in an
if
orwhile
condition or as operand of the Boolean operations below. The following values are considered false:
None
False
- ...
Since not seen_add(x)
is always True
, it has no effect on the result of the if
. It is only used for the side effect of adding x
to seen
.
Put another way, the following:
seen_add = seen.add
return [ x for x in seq if x not in seen and not seen_add(x)]
is a shorter (and likely more performant) way to write:
result = []
for x in seq:
if x not in seen:
result.append(x)
seen.add(x)
return result
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With