Printing a table of letter frequencies using Python What is the recommended (standard, cleaner, more elegant, etc.) method in Python to get a string with all the alphabet letters?

Here's three versions of code to generate a dictionary with keys as letters and 0 as all values. The aim is to parse a text and count how often a letter appears.



from string import ascii_lowercase
frequency = {letter: 0 for letter in ascii_lowercase}


A downside of this method is that the constant shows up in the pydoc output for the module in which it is imported.



frequency = {chr(letter): 0 for letter in range(ord('a'), ord('z')+1)}




frequency = {letter: 0 for letter in 'abcdefghijklmnopqrstuvwxyz'}




This is the snippet of code where it is used:

frequency = {chr(letter): 0 for letter in range(ord('a'), ord('z')+1)}

# The 'text' variable is taken from somewhere else, we define it here for example's sake
text = 'StackExchange Code Review'
for c in text.lower():
    if c in frequency.keys():
        frequency[c] += 1
        total += 1

output = OrderedDict(sorted(frequency.items(), key = lambda x: x[0]))
for l in output.keys():
    print(l + ':' + '{:&gt;8}'.format(output[l]) + '{:9.2f}'.format(100 * output[l] / (total if total &gt; 0 else 1)) + ' %')
The printing portion should be simplified:


The use of OrderedDict is superfluous.  A list of pairs would suffice.
I'd prefer to stick to the same iteration variable, when it is used to refer to the same thing.  Choose either c or l.
You are not using str.format() effectively.
(total if total &gt; 0 else 1) could just be (total or 1).




for c, n in sorted(frequency.items()):
    print('{}:{:&gt;8}{:9.2f}%'.format(c, n, 100 * n / (total or 1)))


As for the counting process itself, you could write c in frequency instead of c in frequency.keys().  But, really, the task is so naturally suited to a collections.Counter that it would be silly not to use it.



from collections import Counter as _Counter
from string import ascii_lowercase as _ascii_lowercase

text = 'StackExchange Code Review'
frequency = _Counter({c: 0 for c in _ascii_lowercase})
frequency.update(c for c in text.lower() if c in frequency)

total = sum(frequency.values())
print('\n'.join(
    '{}:{:&gt;8}{:9.2f}%'.format(c, n, 100 * n / (total or 1))
    for c, n in sorted(frequency.items())
))


I think that the call to sorted() should be optional as of Python 3.6.