0

I have a list, for example:

res = [['a', 'b', 'a'], ['a', 'b', 'c'], ['a']]

I want to count how many lists contains a specific letter. For instance, 'a' is contained in 3 lists, 'b' is contained in 2 lists and 'c' is contained in 1 list.

The code below is what I have so far:

count=0
docs='a'

list1=[]

for c in range(len(res)):
    for i in res[0]:
        list1.append(i)
        for i in list1:
            if i == docs:
                count=1
print count
Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
sjain
  • 15
  • 3

2 Answers2

5

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
Zero Piraeus
  • 56,143
  • 27
  • 150
  • 160
  • You're welcome :-) If you like, you can [accept](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235) either my or Mark Tolonen's answer to let future readers know that it solved your problem. – Zero Piraeus Feb 19 '15 at 03:14
  • i dont have enough reputation to select the answer. i recently joined stackoverflow – sjain Feb 19 '15 at 03:31
  • You can't vote up yet, but you can accept (the check mark under the vote up/down buttons). The [link](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work/5235#5235) I included in my previous comment explains more ... – Zero Piraeus Feb 19 '15 at 03:41
  • (by the way, I'm not trying to be pushy, just informative :-) Of course you should only accept an answer you truly feel solves your issue) – Zero Piraeus Feb 19 '15 at 03:43
  • no you are not being pushy, since i am new its very good to know. thank you for that. – sjain Feb 19 '15 at 03:46
2

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
Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
  • i tried this way, it says Typeerror: 'int' object is not callable. i am new to python,so very hard to predict the behavior. – sjain Feb 19 '15 at 03:34
  • @sjain Mark's answer works for me — are you sure you typed it correctly? – Zero Piraeus Feb 19 '15 at 03:50
  • its showing me above mentioned error at sum('a' in x for x in L) I did it the same way – sjain Feb 19 '15 at 03:53
  • Ah, you must have created a variable called `sum` then. If you exit Python and start again (taking care not to create a `sum` variable), you should find that it works. – Zero Piraeus Feb 19 '15 at 03:54
  • @sjain [this question](http://stackoverflow.com/questions/16523789/python-naming-conflict-with-built-in-function) might help you understand what happened there ... – Zero Piraeus Feb 19 '15 at 03:58