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
0

2 Answers 2

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
Sign up to request clarification or add additional context in comments.

5 Comments

You're welcome :-) If you like, you can accept either my or Mark Tolonen's answer to let future readers know that it solved your problem.
i dont have enough reputation to select the answer. i recently joined stackoverflow
You can't vote up yet, but you can accept (the check mark under the vote up/down buttons). The link I included in my previous comment explains more ...
(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)
no you are not being pushy, since i am new its very good to know. thank you for that.
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

5 Comments

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 Mark's answer works for me — are you sure you typed it correctly?
its showing me above mentioned error at sum('a' in x for x in L) I did it the same way
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.
@sjain this question might help you understand what happened there ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.