3

this is my program on counting the number of vowels

'''Program to count number of vowels'''
str=input("Enter a string\n")
a=0
e=0
i=0
o=0
u=0
for x in str:
    if x=='a':
        a=a+1
        continue
    if x=='e':
        e=e+1
        continue
    if x=='i':
        i=i+1
        continue
    if x=='o':
        o=o+1
        continue
    if x=='u':
        u=u+1
        continue
count={}
if a>0:
    count['a']=a
if e>0:
    count['e']=e
if i>0:
    count['i']=i
if o>0:
    count['o']=o
if u>0:
    count['u']=u
print(count)

How can I improve the initial loop for comparison along with the process of filling the dictionary.

While running the program several times I have obtained the following output:

>>> 
Enter a string
abcdefgh
{'e': 1, 'a': 1}
>>> ================================ RESTART ================================
>>> 
Enter a string
abcdefghijklmnopqrstuvwxyz
{'u': 1, 'a': 1, 'o': 1, 'e': 1, 'i': 1}
>>> ================================ RESTART ================================
>>> 
Enter a string
abcdeabcdeiopiop
{'a': 2, 'o': 2, 'i': 2, 'e': 2}

From this I could not figure out how exactly are the key value pairs being added to the dictionary count against my expectation of:

Case 1:
{'a':1, 'e':1}
Case 2:
{'a':1, 'e':1, 'i':1, 'o':1, 'u':1}
Case 3:
{'a':2, 'e':2, 'i':2, 'o':2}

Any help is appreciated.

  • Do you simply mean you are surprised by the order of keys in the dictionary? – jonrsharpe Dec 24 '13 at 11:09
  • 1
    Dictionaries don't maintain order. So, your program is working fine only. Incase you want to maintain the Order in which the keys are inserted, you need to use `Collections.OrderedDict` – thefourtheye Dec 24 '13 at 11:09

3 Answers3

4
>>> import collections
>>> s = "aacbed"
>>> count = collections.Counter(c for c in s if c in "aeiou")
>>> count
Counter({'a': 2, 'e': 1})

Or - if you really need to maintain insertion order:

>>> s = 'debcaa'
>>> count=collections.OrderedDict((c, s.count(c)) for c in s if c in "aeiou")
>>> count
OrderedDict([('e', 1), ('a', 2)])

Finally if you want lexicographic ordering, you can either turn your dict/counter/ OrderedDict into a list of tuples:

>>> sorted(count.items())
[('a', 2), ('e', 1)]

and if you want a lexicographically OrderedDict:

>>> sorted_count = collections.OrderedDict(sorted(count.items()))
>>> sorted_count
OrderedDict([('a', 2), ('e', 1)])
bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
  • `collections.OrderedDict((c, s.count(c)) for c in s if c in "aeiou")` - quadratic time, and it doesn't produce the `aeiou` order the OP expected anyway. – user2357112 Dec 24 '13 at 11:38
1

Just put a=0 e=0 i=0 o=0 u=0 inside a dictionary like that:

myDict = {'a':0, 'e':0, 'i':0, 'o':0, 'u':0}
for x in string:
    myDict[x] += 1 
print myDict

If the value is not one of the following then a raise of KeyError will come up.

So you can do something like that:

myDict = {'a': 0, 'e': 0, 'i': 0, 'o': 0, 'u': 0}
for x in string:
    try:
        myDict[x] += 1
    except KeyError:
        continue
print myDict

Note: I've changed the name str to string

You can also see a very good solution by @Amber here

Community
  • 1
  • 1
Kobi K
  • 7,743
  • 6
  • 42
  • 86
1

A more Pythonic way to do what you want is:

'''Program to count number of vowels'''
s = input("Enter a string\n")
count = {v: s.count(v) for v in "aeiou" if s.count(v) > 0}
print(count)

You shouldn't use str as a variable name, as that is the name of the built-in string type.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437