1

im new to Python3.3 and i wanted to eliminate repetitive members from a list, i found this short code on the net , but i don't know what is the logic behind this code? ,especially the part "not seen_add(x)"!.

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)]

can someone clear this up for me?!

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
Masih
  • 920
  • 2
  • 19
  • 36

1 Answers1

2

The add method of a set always returns None. None is considered false in a boolean context, so not seen_add(x) is always True. and short-circuits, so seen_add(x) is only executed if x wasn't registered as seen. The seen_add(x) is to keep track of the fact that x has now been seen, not to filter anything, which is why not seen_add(x) is always true.

Turning the list comprehension into an equivalent loop, we have

def f7(seq):
    seen=set()
    seen_add=seen.add
    result = []
    for x in seq:
        if x not in seen and not seen_add(x):
            result.append(x)
    return result

Converting the and to a more readable form, and eliminating the seen_add microoptimization, the code you found is equivalent to the following:

def f7(seq):
    seen=set()
    result = []
    for x in seq:
        if x not in seen:
            seen.add(x)
            result.append(x)
    return result
user2357112
  • 260,549
  • 28
  • 431
  • 505
  • So it's the same thing as `list(set(seq))`? :P – anton.burger Dec 03 '13 at 09:42
  • 3
    @shambulator: No, because this code takes special care to make sure the output is ordered by the first occurence of each element in the input. `list(set(seq))` is something you'd use if you didn't care about order. – user2357112 Dec 03 '13 at 09:45
  • 2
    @shambulator It's basically a golfed version of the `unique_everseen` recipe from itertools. You'll also see `list(collections.OrderedDict.fromkeys(seq))` crop up a bit for this as well. – Jon Clements Dec 03 '13 at 09:49