theage
theage

Reputation: 289

Construct list of numbers of occurrences in list

Suppose I am given a list of elements such as

[1,1,2,3,3,1,2]

or

["a","a","b","c","c"]

Given such a list, I would like to construct a (not necessarily ordered) list containing the number of occurrences of each element. For instance, the first list should return

[3,2,2]

as there are 3 ones, 2 twos, and 3 threes in the list. The second should similarly return

[2,1,2]

What is the best way to go about this in Python?

Upvotes: 2

Views: 79

Answers (4)

Kasravnd
Kasravnd

Reputation: 107287

You can use list.count,within a list comprehension but note that you may use set for checking the membership as its more efficient for this aim :

>>> l=[1,1,2,3,3,1,2]
>>> [l.count(i) for i in set(l)]
[3, 2, 2]

As you can see in the following bench mark, using this recipe is 7 time faster:

:~$ python -m timeit "l=[1,1,2,3,3,1,2];[l.count(i) for i in set(l)]"
1000000 loops, best of 3: 0.718 usec per loop
:~$ python -m timeit "l=[1,1,2,3,3,1,2];[l.count(i) for i in l]"
1000000 loops, best of 3: 0.97 usec per loop
:~$ python -m timeit "l=[1,1,2,3,3,1,2];from collections import Counter;Counter([1, 1, 2, 3, 3, 1, 2]).values()"
100000 loops, best of 3: 7.27 usec per loop

Upvotes: 1

FuzzyDuck
FuzzyDuck

Reputation: 1521

In 'pure' Python:

x = [1,1,2,3,3,1,2]
y = [x.count(u) for u in set(x)]
>>> y
[3, 2, 2]

In the spirit of Kasra's benchmark, using the simple list comprehension is twice as fast as the next solution, although there is probably some overhead in the module import in the first three methods:

>>> print ' first: ' ,timeit(stmt=s1, number=100000)
 first:  0.358644798424
>>> print ' second: ' ,timeit(stmt=s2, number=100000)
 second:  0.466576073569
>>> print ' third: ' ,timeit(stmt=s3, number=100000)
 third:  0.685125215535
>>> print ' fourth: ' ,timeit(stmt=s4, number=100000)
 fourth:  0.143517940718

Upvotes: 0

Vivek Sable
Vivek Sable

Reputation: 10213

Best to create dictionary (key-value) to have every unique value as key and its occurrence in the given list.

>>> l
[1, 1, 2, 3, 3, 1, 2]
>>> import collections
>>> d = collections.Counter(l)
>>> print d
Counter({1: 3, 2: 2, 3: 2})
>>> 

Upvotes: 1

thefourtheye
thefourtheye

Reputation: 239473

construct a (not necessarily ordered) list containing the number of occurrences of each element

Since you are not worried about the order, you can simply use collections.Counter, like this

>>> from collections import Counter
>>> Counter([1, 1, 2, 3, 3, 1, 2]).values()
[3, 2, 2]
>>> Counter(["a", "a", "b", "c", "c"]).values()
[2, 2, 1]

The Counter object is nothing but a dictionary, with the keys found in the iterable and the values will be the actual number of times the corresponding key found in the iterable. You can print the Counter object and check that, like this

>>> Counter([1, 1, 2, 3, 3, 1, 2])
Counter({1: 3, 2: 2, 3: 2})
>>> Counter(["a", "a", "b", "c", "c"])
Counter({'a': 2, 'c': 2, 'b': 1})

Since you are interested only in the number of times of occurrences, we are taking only the values().

Upvotes: 4

Related Questions