2

I want to do a function that counts the consonants in a string, so I tried to do this:

def vowel_count(foo):
  count = 0
  for i in foo:
    if not i == 'a' and i == 'e' and i ... and i == 'O' and i == 'U':
      count += 1
return count

But this is pretty ugly and tedious to do, more so with many more conditions. Is there any way to put them together?

3
  • 6
    i.lower() in "aeiou" ? Commented Aug 13, 2018 at 12:30
  • 2
    Also note that your original code does not do what you want. not a and b and c is understood as (not a) and b and c, which is quite different from not (a and b and c). It is pretty hard for a character to be "e" and "O" and "U" all at the same time, even if it is not "a". Commented Aug 13, 2018 at 12:32
  • sum(c for k, c in collections.Counter(i.lower()) if k in 'aeiou') Commented Aug 13, 2018 at 12:33

2 Answers 2

6

You are looking for the not in operator.

def vowel_count(foo):
    count = 0
    for i in foo.lower():
        if i not in 'aeiou':
            count += 1
    return count

or more simply:

def vowel_count(foo):
    return sum(i not in 'aeiou' for i in foo.lower())  # True == 1, False == 0
Sign up to request clarification or add additional context in comments.

6 Comments

is it better to build the set first once? Also I thought using ... if i not in was normally faster than cooercing i not in ... from bool to int?
No need to do set(...) -- it's much slower. It's creating a set from the string on each iteration. You can use set operations instead.
@warvariuc I was working under the incorrect assumption that the optimizer would create the set at compile time. Also, though technically in is an O(n) operation for a string, it's such a short string that the string is still slightly faster than the set.
Or, in short, beware premature optimization ;)
@warvariuc: You could make a set of counted (or discounted) characters, either before the loop or even outside the function. I don't see why it would need to be constructed each iteration... The question is just whether in works better for set or for str (I suspect set but won't state it firmly without profiling) but you can definitely build a set without it impacting performance.
|
0

Use a container to store vowels in their lower form:

def vowel_count(foo):
    vowel = ["a", "e", "i", "o", "u", "y"]
    count = 0
    for i in foo:
        if i.lower() not in vowel:
            count += 1

Then you could also do this a bit differently with a filter for instance.

def condition(letter):
    vowel = ["a", "e", "i", "o", "u", "y"]
    if letter.lower() not in vowel and letter != " ":
        return True
    else:
        return False

foo = 'bnojouearoui okeorjaji '
count = len(list(filter(condition, foo)))

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.