I would like to filter this list,
l = [0,1,1,2,2]
to only leave,
[0].
I\'m struggling to do it in a \'pythoni
I think the actual timings are kind of interesting:
Alex' answer:
python -m timeit -s "l = range(1,1000,2) + range(1,1000,3); import collections" "d = collections.defaultdict(int)" "for x in l: d[x] += 1" "l[:] = [x for x in l if d[x] == 1]"
1000 loops, best of 3: 370 usec per loop
Mine:
python -m timeit -s "l = range(1,1000,2) + range(1,1000,3)" "once = set()" "more = set()" "for x in l:" " if x not in more:" " if x in once:" " more.add(x)" " once.remove( x )" " else:" " once.add( x )"
1000 loops, best of 3: 275 usec per loop
sepp2k's O(n**2) version, to demonstrate why compexity matters ;-)
python -m timeit -s "l = range(1,1000,2) + range(1,1000,3)" "[x for x in l if l.count(x)==1]"
100 loops, best of 3: 16 msec per loop
Roberto's + sorted:
python -m timeit -s "l = range(1,1000,2) + range(1,1000,3); import itertools" "[elem[0] for elem in itertools.groupby(sorted(l)) if elem[1].next()== 0]"
1000 loops, best of 3: 316 usec per loop
mhawke's:
python -m timeit -s "l = range(1,1000,2) + range(1,1000,3)" "d = {}" "for i in l: d[i] = d.has_key(i)" "[k for k in d.keys() if not d[k]]"
1000 loops, best of 3: 251 usec per loop
I like the last, clever and fast ;-)
Here's another dictionary oriented way:
l = [0, 1, 1, 2, 2]
d = {}
for i in l: d[i] = i in d
[k for k in d if not d[k]] # unordered, loop over the dictionary
[k for k in l if not d[k]] # ordered, loop over the original list
In the same spirit as Alex's solution you can use a Counter/multiset (built in 2.7, recipe compatible from 2.5 and above) to do the same thing:
In [1]: from counter import Counter
In [2]: L = [0, 1, 1, 2, 2]
In [3]: multiset = Counter(L)
In [4]: [x for x in L if multiset[x] == 1]
Out[4]: [0]
[x for x in the_list if the_list.count(x)==1]
Though that's still a nested loop behind the scenes.
l = [0,1,2,1,2]
def justonce( l ):
once = set()
more = set()
for x in l:
if x not in more:
if x in once:
more.add(x)
once.remove( x )
else:
once.add( x )
return once
print justonce( l )
>>> l = [0,1,1,2,2]
>>> [x for x in l if l.count(x) is 1]
[0]