I have a list, for example:
res = [[\'a\', \'b\', \'a\'], [\'a\', \'b\', \'c\'], [\'a\']]
I want to count how many lists contains a specific le
A simple list comprehension does the trick.
>>> L=[['a', 'b', 'a'], ['a', 'b', 'c'], ['a']]
>>> ['a' in x for x in L]
[True, True, True]
>>> ['b' in x for x in L]
[True, True, False]
Using the knowledge that True
is considered 1
:
>>> sum('a' in x for x in L)
3
>>> sum('b' in x for x in L)
2
>>> sum('c' in x for x in L)
1
When you find yourself saying "I want to count how many ...", there's a good chance Counter(), from the collections
module, can help.
In this case, we want to count how many lists each letter occurs in. Since we don't want to count any letter more than once for each sublist, we'll convert them to sets:
>>> res = [['a', 'b', 'a'], ['a', 'b', 'c'], ['a']]
>>> [set(x) for x in res]
[{'b', 'a'}, {'c', 'b', 'a'}, {'a'}]
The order gets mixed up, but that doesn't matter, as long as we only have one letter from each list.
Now we want to join those sets of letters into one sequence, so we can count them all. We could do it like this:
>>> [s for x in res for s in set(x)]
['b', 'a', 'c', 'b', 'a', 'a']
... but that's a little hard to follow. Luckily there's a function in the itertools
module called chain() that does the same thing and is a little easier to read. We want the chain.from_iterable()
version:
>>> from itertools import chain
>>> c = chain.from_iterable(set(x) for x in res)
>>> list(c)
['b', 'a', 'c', 'b', 'a', 'a']
Don't worry about that list(c)
too much - chain()
returns an iterator, which means nothing gets calculated until we actually do something with the result (like make it into a list), so I did that to show what it produces.
Anyway, all we need to do now is pass that sequence to Counter()
:
>>> from collections import Counter
>>> Counter(chain.from_iterable(set(x) for x in res))
Counter({'a': 3, 'b': 2, 'c': 1})
Here's the whole thing:
from collections import Counter
from itertools import chain
res = [['a', 'b', 'a'], ['a', 'b', 'c'], ['a']]
letter_count = Counter(chain.from_iterable(set(x) for x in res))
print(letter_count['a']) # prints 3