You are on page 1of 3

1/24/2016

pythonCountvowelsfromrawinputStackOverflow

help

Countvowelsfromrawinput

Ihaveahomeworkquestionwhichaskstoreadastringthroughrawinputandcounthowmanyvowelsareinthestring.ThisiswhatIhaveso
farbutIhaveencounteredaproblem:
defvowels():
vowels=["a","e","i","o","u"]
count=0
string=raw_input("Enterastring:")
foriinrange(0,len(string)):
ifstring[i]==vowels[i]:
count=count+1
printcount
vowels()

Itcountsthevowelsfine,butdueto ifstring[i]==vowels[i]: ,itwillonlycountonevowelonceas i keepsincreasingintherange.HowcanI


changethiscodetochecktheinputtedstringforvowelswithoutencounteringthisproblem?
python string count
editedJul15'15at15:41

askedOct4'12at2:40

durron597
22k

10

user1679073
45

80

27

3 Howaboutaninnerlooptogooveryourlistofvowels?gtgaxiolaOct4'12at2:42
@gtgaxiolaHowexactlydoIgoaboutdoingthat? user1679073 Oct4'12at2:42

5Answers

in

operator

Youprobablywanttousethe in operatorinsteadofthe == operatorthe in operatorletsyou


checktoseeifaparticularitemisinasequence/set.
1in[1,2,3]#True
1in[2,3,4]#False
'a'in['a','e','i','o','u']#True
'a'in'aeiou'#AlsoTrue

Someothercomments:

Sets
The in operatorismostefficientwhenusedwitha set ,whichisadatatypespecifically
designedtobequickfor"isitemXpartofthissetofitems"kindofoperations.*
vowels=set(['a','e','i','o','u'])

* dict sarealsoefficientwith in ,whichcheckstoseeifakeyexistsinthedict.

Iteratingonstrings
AstringisasequencetypeinPython,whichmeansthatyoudon'tneedtogotoalloftheeffortof
gettingthelengthandthenusingindicesyoucanjustiterateoverthestringandyou'llgeteach
characterinturn:
E.g.:
forcharacterinmy_string:
ifcharacterinvowels:
#...

Initializingasetwithastring
Above,youmayhavenoticedthatcreatingasetwithpresetvalues(atleastinPython2.x)

http://stackoverflow.com/questions/12719600/countvowelsfromrawinput/12719624#12719624

1/3

1/24/2016

pythonCountvowelsfromrawinputStackOverflow

involvesusingalist.Thisisbecausethe set() typeconstructortakesasequenceofitems.You


mayalsonoticethatintheprevioussection,ImentionedthatstringsaresequencesinPython
sequencesofcharacters.
Whatthismeansisthatifyouwantasetofcharacters,youcanactuallyjustpassastringof
thosecharacterstothe set() constructoryoudon'tneedtohavealistonesinglecharacter
strings.Inotherwords,thefollowingtwolinesareequivalent:
set_from_string=set('aeiou')
set_from_list=set(['a','e','i','o','u'])

Neat,huh?:)Donote,however,thatthiscanalsobiteyouifyou'retryingtomakeasetof
strings ,ratherthanasetofcharacters .Forinstance,thefollowingtwolinesarenotthesame:
set_with_one_string=set(['cat'])
set_with_three_characters=set('cat')

Theformerisasetwithoneelement:
'cat'inset_with_one_string#True
'c'inset_with_one_string#False

Whereasthelatterisasetwiththreeelements(eachoneacharacter):
'c'inset_with_three_characters`#True
'cat'inset_with_three_characters#False

Casesensitivity
Comparingcharactersiscasesensitive. 'a'=='A' isFalse,asis 'A'in'aeiou' .Toget
aroundthis,youcantransformyourinputtomatchthecaseofwhatyou'recomparingagainst:
lowercase_string=input_string.lower()
editedOct4'12at3:13

answeredOct4'12at2:44

Amber
216k

30

366

383

OhwowIthinkthisdidit.Thanksforthatbitofinformationitwilldefinitelycomeinhandy. user1679073
Oct4'12at2:45
1 greatanswer!holycowJoranBeasley Oct4'12at2:52
Agreed,quiteanexplanation!+1squiguy Oct4'12at2:56

Youcansimplifythiscode:
defvowels():
vowels='aeiou'
count=0
string=raw_input("Enterastring:")
foriinstring:
ifiinvowels:
count+=1
printcount

StringsareiterableinPython.
editedOct4'12at2:52

answeredOct4'12at2:42

squiguy
13k

26

41

+1EvenbetterthisapproachgtgaxiolaOct4'12at2:43
@nneonneoFixed,thankyou.squiguy Oct4'12at2:44
1 also,(nitpick), count+=1 nneonneoOct4'12at2:44
TIMTOWTDIThereIsMoreThanOneWayToDoIt:)squiguy Oct4'12at2:46
But,"Thereshouldbeoneandpreferablyonlyoneobviouswaytodoit."nneonneoOct4'12at2:47

http://stackoverflow.com/questions/12719600/countvowelsfromrawinput/12719624#12719624

2/3

1/24/2016

pythonCountvowelsfromrawinputStackOverflow

foriinrange(0,len(string)):
ifstring[i]==vowels[i]:

Thisactuallyhasasubtlerproblemthanonlycountingeachvowelonceitactuallyonlytestsif
thefirstletterofthestringisexactly a ,ifthesecondisexactly e andsoon..untilyougetpast
thefifth.Itwilltrytotest string[5]==vowels[5] whichgivesanerror.
Youdon'twanttouse i tolookinto vowels ,youwantanestedloopwithasecondindexthat
willmakesensefor vowels eg,
foriinrange(len(string)):
forjinrange(len(vowels)):
ifstring[i]==vowels[j]:
count+=1

Thiscanbesimplifiedfurtherbyrealisingthat,inPython,youveryrarelywanttoiterateoverthe
indexes intoasequencethe for loopknowshowtoiterateovereverythingthatyoucando
string[0] , string[1] andsoon,giving:
forsinstring:
forvinvowels:
ifs==v:
count+=1

Theinnerloopcanbesimplifiedusingthe in operationonlistsitdoesexactlythesamething
asthiscode,butitkeepsyourcode'slogicatahigherlevel(whatyouwanttodovs.howtodo
it):
forsinstring:
ifsinvowels:
count+=1

Now,itturnsoutthatPythonletsdomathwithbooleans(whichiswhat sinvowels givesyou)


andints True behavesas 1 , False as 0 ,so True+True+False is 2 .Thisleadstoaone
linerusingageneratorexpressionandsum:
sum(sinvowelsforsinstring)

Whichreadsas'foreverycharacterin string ,counthowmanyarein vowels '.


answeredOct4'12at2:56

lvc
16.3k

24

59

youcanusefilterforaoneliner
printlen(filter(lambdach:ch.lower()in"aeiou","ThisisaString"))
answeredOct4'12at2:49

JoranBeasley
46.2k

37

68

Here'samorecondensedversionusing sum withagenerator:


defvowels():
string=raw_input("Enterastring:")
printsum(1forxinstringifx.lower()in'aeiou')
vowels()
answeredOct4'12at2:53

MuMind
6,187

17

49

1 Youcansumboolsdirectly(boolsubclassesint) sum(x.lower()in'aeiou'forxinstring) .lvc


Oct4'12at2:58

http://stackoverflow.com/questions/12719600/countvowelsfromrawinput/12719624#12719624

3/3

You might also like