Python filter a list to only leave objects that occur once

前端 未结 9 747
野的像风
野的像风 2020-12-15 13:18

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

相关标签:
9条回答
  • 2020-12-15 13:56

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

    0 讨论(0)
  • 2020-12-15 13:59

    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
    
    0 讨论(0)
  • 2020-12-15 13:59

    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]
    
    0 讨论(0)
  • 2020-12-15 14:00
    [x for x in the_list if the_list.count(x)==1]
    

    Though that's still a nested loop behind the scenes.

    0 讨论(0)
  • 2020-12-15 14:00
    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 )
    
    0 讨论(0)
  • 2020-12-15 14:02
    >>> l = [0,1,1,2,2]
    >>> [x for x in l if l.count(x) is 1]
    [0]
    
    0 讨论(0)
提交回复
热议问题