Skip to content

Instantly share code, notes, and snippets.

@hughdbrown
Created December 12, 2015 23:32
Show Gist options
  • Save hughdbrown/c5250fab438fb28fa0d7 to your computer and use it in GitHub Desktop.
Save hughdbrown/c5250fab438fb28fa0d7 to your computer and use it in GitHub Desktop.
Ordered unique elements
# An occasional python interview question I have seen is:
# "How would you make this series unique while preserving order?"
# The standard code looks like this:
def unique2(series):
result = []
seen = set()
for s in series:
if s not in seen:
seen.add(s)
result.append(s)
return result
# And this works. Here is the extra clever python-y code you can write instead:
def unique(series):
seen = set()
return [seen.add(s) or s for s in series if s not in seen]
# The tricky part is that `set.add` returns `None` so if you `or` that with a value,
# you get the value plus the side effect of modifying the `set`. And if you compare the
# disassembled code (using the `dis` module), you can see how much shorter the clever
# code is:
```
from dis import dis
>>> dis(unique)
2 0 LOAD_GLOBAL 0 (set)
3 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
6 STORE_DEREF 0 (a)
3 9 LOAD_CLOSURE 0 (a)
12 BUILD_TUPLE 1
15 LOAD_CONST 1 (<code object <listcomp> at 0x10deb6390, file "<stdin>", line 3>)
18 LOAD_CONST 2 ('unique3.<locals>.<listcomp>')
21 MAKE_CLOSURE 0
24 LOAD_FAST 0 (series)
27 GET_ITER
28 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
31 RETURN_VALUE
>>> dis(unique2)
2 0 BUILD_LIST 0
3 STORE_FAST 1 (result)
3 6 LOAD_GLOBAL 0 (set)
9 CALL_FUNCTION 0 (0 positional, 0 keyword pair)
12 STORE_FAST 2 (seen)
4 15 SETUP_LOOP 52 (to 70)
18 LOAD_FAST 0 (series)
21 GET_ITER
>> 22 FOR_ITER 44 (to 69)
25 STORE_FAST 3 (s)
5 28 LOAD_FAST 3 (s)
31 LOAD_FAST 2 (seen)
34 COMPARE_OP 7 (not in)
37 POP_JUMP_IF_FALSE 22
6 40 LOAD_FAST 2 (seen)
43 LOAD_ATTR 1 (add)
46 LOAD_FAST 3 (s)
49 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
52 POP_TOP
7 53 LOAD_FAST 1 (result)
56 LOAD_ATTR 2 (append)
59 LOAD_FAST 3 (s)
62 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
65 POP_TOP
66 JUMP_ABSOLUTE 22
>> 69 POP_BLOCK
8 >> 70 LOAD_FAST 1 (result)
73 RETURN_VALUE
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment