Python Forum

Full Version: a better way of writing code
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi is there a better way of writing this code instead of writing the repetitive multiple if statements? I'm trying to find a better way of writing this code. Basically I want to count up the the total number of matching letters in the given string s.

s = 'abcdbobbobbegkhl'
count = 0
for letter in s:
    if letter == 'a':
        count += 1
    if letter == 'e':
        count += 1
    if letter == 'i':
        count += 1
    if letter == 'o':
        count += 1
    if letter == 'u':
        count += 1
print('Number of vowels: ' + str(count))
count = 0
for letter in s:
    if letter in ('aeiou'):
        count += 1
print('Number of vowels: ' + str(count))
Output:
Number of vowels: 4

count = sum(s.count(letter) for letter in ('aeiou'))
print(f'Number of vowels: {count}')
Output:
Number of vowels: 4

import collections

letter_count = collections.Counter(s)
count = sum(letter_count[letter] for letter in ('aeiou'))
print(f'Number of vowels: {count}')
Output:
Number of vowels: 4
s = 'abcdbobbobbegkhl'
vowels = 'aeiou'
vowel_count = 0
for letter in s:
    if letter in vowels:
        vowel_count += 1
print(f'Number of vowels: {vowel_count}')
s = 'abcdbobbobbegkhl'
vowels = 'aeiou'
vowel_count = len([letter for letter in s if letter in vowels])
#vowel_count = sum([1 for letter in s if letter in vowels])
print(f'Number of vowels: {vowel_count}')
import re
s = 'abcdbobbobbegkhl'
count = len(re.findall(r"[aeiou]", s))
>>> s = 'abcdbobbobbegkhl'
>>> sum(map(s.count, 'aeiou'))
4
Here's my preferred solution:
vowels = set("aeiou")
sum(char in vowels for char in s)
This takes advantage of Python letting you sum() booleans. I think it reads like English and is Pythonic. (In a larger program, I'd probably name VOWELS as a constant.)

I avoid some particular things for some particular reasons...

I avoided count() because it has to be called for each vowel, causing a multiplication when calculating such algoritms' runtimes. I used a set because they're constant-time lookup, and usually fast; if I really cared about the speed, I'd test to see if a linear search through the string is faster. And if my manager has told me to speed it up I'd check tuples too :)

I avoid map() in Python because I think comprehensions are clearer, and because I think map() should be a method rather than a global function. (This is one place Scala beats Python in my mind. In Python, nesting comprehensions or map calls sucks. But collection.map(foo).map(bar).map(baz) can be spread across multiple lines nicely, if the functions are are defined in-line.)

I avoided len() because it requires creating an intermediate collection. sum() can be passed a generator expression which uses constant-time memory.
s = 'abcdbobbobbegkhl'
count = len([x for x in s if x in 'aeiou'])
print(f"There are {count} vowels in the string")