2

Possible Duplicate:
How can I make my code be a set?
python takes list and returns only if negative value also exists using set

Basically I have a huge list:

# with (n) being a number in the hundreds of thousands or millions
def big_list(n):
return [ randrange(n) for i in range(n) ]

What I need to do is create a new list containing only the elements of big_list(n) that appear once using set. I'm really stuck so anything that could point me in the right direction would be awesome!

Community
  • 1
  • 1
iamtesla
  • 423
  • 2
  • 5
  • 18
  • This is exactly the same as [How can I make my code be a set? - Python](http://stackoverflow.com/questions/12886450/how-can-i-make-my-code-be-a-set-python) – Gareth Latty Oct 14 '12 at 22:11
  • You're right, haha looks like I'm not the only one in my class thats confused. Thank you. – iamtesla Oct 14 '12 at 22:34

5 Answers5

4
l
Out[225]: [1, 2, 3, 45, 2, 2, 34, 5, 64, 5, 6, 45, 1, 1, 2, 3, 4, 6, 64, 3]

[x for x in l if l.count(x)==1]
Out[226]: [34, 4]

or use defaultdict from the collections,if perfomance matters:

In [228]: import collections
     ...: d = collections.defaultdict(int)
     ...: for x in l: d[x] += 1
     ...: results = [x for x in l if d[x] == 1]
     ...: 

In [229]: results
Out[229]: [34, 4]
root
  • 76,608
  • 25
  • 108
  • 120
1

Store the counting in a dict and filter the elements with count==1, dict keys are already unique.

[update]

Untested, please fix any bug yourself:

def filter_single_elements(big_list):
    counter = {}
    for element in big_list:
        counter[element] = counter.get(element, 0) + 1
    new_list = []
    for element, count in counter.items():
        if count == 1:
            new_list.append(element)
    return new_list

This returns a new list. You may try to make a generator instead:

def filter_single_elements_iter(big_list):
    counter = {}
    for element in big_list:
        counter[element] = counter.get(element, 0) + 1
    for element, count in counter.items():
        if count == 1:
            yield element
Paulo Scardine
  • 73,447
  • 11
  • 124
  • 153
1

If I'm understanding correctly, you want only the items that appear exactly once in the big list. Here is how you can do it (where x is your list):

>>> from collections import Counter
>>>
>>> x = [1, 1, 2, 3, 4, 5, 5, 6]
>>> y = []
>>>
>>> for item, count in Counter(x).most_common():
...     if count == 1:
...         y.append(item)
...
>>> y
[2, 3, 4, 6]

Note that collections.Counter is 2.7+ only.

Liquid_Fire
  • 6,990
  • 2
  • 25
  • 22
0

use a generator expression in the set constructor:

def big_list(n):
    return set(randrange(n) for i in xrange(n))

EDIT

As the comment bellow pointed out, you seek elements that appear once. I suggest you have a look at counter object. You can use them for efficient tallying of the elements in your big list, and than iterate over the counter to sieve out the ones you need.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • 1
    The OP is looking for elements that appear once, not one of each element that appears. Also, in 2.7+, you can use a set comprehension (``{randrange(n) for i in xrange(n)}``). – Gareth Latty Oct 14 '12 at 22:12
0

Convert big_list into a generator and apply the unique_everseen recipe from itertools

iruvar
  • 22,736
  • 7
  • 53
  • 82
  • This doesn't work. It returns each element once, not each element that has a count of 1. – vy32 Mar 14 '17 at 13:14