Home > Blockchain >  Counting the occurrences of letters directly in a list of words with dictionaries
Counting the occurrences of letters directly in a list of words with dictionaries

Time:11-23

I have problems in counting with a dictionary the occurrences of letters in a list of words of different length for each index of letters. The list is ordered from longest to shortest word. Like so:

main_list = ['elephant','mouse','tiger','dog']

For index 0 the dictionary should be:
{'e':1,'m':,'t':1,'d':1}

For index 1:
{'l':1,'o':2,'i':1}

For index 2:
{'e':1,'u':1,'g':2}

and so on until the longest word is ended.

The output should be a list of dictionaries:

main_list = [{'e':1,'m':1,'t':1,'d':1},{'l':1,'o':2,'i':1},{'e':1,'u':1,'g':2}...]

(also the shortest word should be included)

To solve the problem I created lists of letters for each index and then made a dictionary to count the occurrences of the letters for each list of letters, but I was wondering if there is a way to count directly in the list of words the occurrences of letters for each index.

CodePudding user response:

You can do the following:

from collections import Counter
from itertools import zip_longest
from pprint import pprint

main_list = ["elephant", "mouse", "tiger", "dog"]

pprint(
    [
        {k: v for k, v in Counter(t).items() if k}
        for t in zip_longest(*main_list, fillvalue=None)
    ]
)

output:

[{'d': 1, 'e': 1, 'm': 1, 't': 1},
 {'i': 1, 'l': 1, 'o': 2},
 {'e': 1, 'g': 2, 'u': 1},
 {'e': 1, 'p': 1, 's': 1},
 {'e': 1, 'h': 1, 'r': 1},
 {'a': 1},
 {'n': 1},
 {'t': 1}]

Since you need to iterate according to the longest word, you need zip_longest instead of zip. Count the characters using Counter class and then filter out the keys that are None.

CodePudding user response:

main_list = ['elephant','mouse','tiger','dog']

from collections import Counter
from itertools import zip_longest

results = [Counter(filter(None,tp)) for tp in zip_longest(*main_list,fillvalue=None)]

for r in results:
    print(r)

# Counter({'e': 1, 'm': 1, 't': 1, 'd': 1})
# Counter({'o': 2, 'l': 1, 'i': 1})
# Counter({'g': 2, 'e': 1, 'u': 1})
# Counter({'p': 1, 's': 1, 'e': 1})
# Counter({'h': 1, 'e': 1, 'r': 1})
# Counter({'a': 1})
# Counter({'n': 1})
# Counter({'t': 1})

Use zip_longest for iterating until the longest element is processed. It requires a fillvalue which I set to None. I also filtered the elements of falsy values (such as this added None). I based it on @Daniel Hao's answer.

CodePudding user response:

You could try to use collections module Counter like this:

Notes: if you want to continue counting to include the shortest word - dog, after exhausting the longest one then you should use zip_longest.

from collections import Counter

results = [Counter(tp) for tp in zip(*main_list) ]  # it ending with longest word

print(results)
# [Counter({'e': 1, 'm': 1, 't': 1, 'd': 1}), Counter({'o': 2, 'l': 1, 'i': 1}), Counter({'g': 2, 'e': 1, 'u': 1})]
  • Related