Reputation: 6896
Input is a string, the idea is to count the letters A-z only, and print them alphabetically with the count of appearances.
As usual I kept at this 'till I got a working result, but now seek to optimize it in order to better understand the Python way of doing things.
def string_lower_as_list(string):
"""
>>> string_lower_as_list('a bC')
['a', ' ', 'b', 'c']
"""
return list(string.lower())
from sys import argv
letters = [letter for letter in string_lower_as_list(argv[1])
if ord(letter) < 124 and ord(letter) > 96]
uniques = sorted(set(letters))
for let in uniques:
print let, letters.count(let)
EDIT Should have said, Python 2.7 on win32
Upvotes: 0
Views: 196
Reputation: 96326
You don't have to convert string to list, string is iterable:
letters = {}
for letter in argv[1].lower():
if "a" <= letter <= "z":
letters[letter] = letters.get(letter, 0) + 1
for letter in sorted(letters.keys()):
print letter, letters[letter]
Upvotes: 1
Reputation: 817208
You can compare letters directly and you actually only need to compare lower case letters
letters = [letter for letter in string_lower_as_list(argv[1])
if "a" <= letter <= "z"]
But better would be to use a dictionary to count the values. letters.count
has to traverse the list every time you call it. But you are already traversing the list to filter out the right characters, so why not count them at the same time?
letters = {}
for letter in string_lower_as_list(argv[1]):
if "a" <= letter <= "z":
letters[letter] = letters.get(letter, 0) + 1
for letter in sorted(letters):
print letter, letters[letter]
Edit: As the others said, you don't have to convert the string to a list. You can iterate over it directly: for letter in argv[1].lower()
.
Upvotes: 2
Reputation: 61643
How do I remove the duplication of ord(letter) in the list comprehension?
You can use a very Python-specific and somewhat magical idiom that doesn't work in other languages: if 96 < ord(letter) < 124
.
Would there have been any benefit in using a Dictionary or Tuple in this instance, if so, how?
You could try using the collections.Counter
class added in Python 2.7.
P.S. You don't need to convert the string to a list in order to iterate over it in the list comprehension. Any iterable will work, and strings are iterable.
P.S. 2. To get the property 'this letter is alphabetic', instead of lowercasing and comparing to a range, just use str.isalpha
. Unicode objects provide the same method, which allows the same code to Just Work with text in foreign languages, without having to know which characters are "letters". :)
Upvotes: 2