This works perfectly
def get_count(sentence):
return sum(1 for letter in sentence if letter in ('aeiou'))
But when I apply the in operator to an array like this, it fails
# Incorrect answer for "aeiou": 0 should equal 5
def get_count(sentence):
return sum(1 for letter in sentence if letter in ['aeiou'])
CodePudding user response:
In the first snippet, ('aeiou')
is a string surrounded by parentheses (which have no syntactic function in this case). The in
is applied to the string, which is itself an iterable, and thus checks if letter
is one of the characters in that string.
In the second snippet, ['aeoiu']
is a list with a single element, the string 'aeiou'
. The in
operator applies to the list, and checks if letter
is one of the elements in the list. It obviously isn't (since letter
is a single character), and thus this condition always evaluates to False
.
CodePudding user response:
('aeiou')
is a string. You can verify this with
>>> x = ('aeiou')
>>> type(x)
<class 'str'>
['aeiou']
on the other hand is a list containing one element which in turn is a string.
>>> x = ['aeiou']
>>> type(x)
<class 'list'>
>>> len(x)
1
>>> type(x[0])
<class 'str'>
When you write if letter in ('aeiou')
, here you are testing if the letter is a substring of the string 'aeiou'
. However, when you write if letter in ['aeiou']
, you are testing if the letter is an element in the list the contains one element, the string 'aeiou'
which is always False
for letter
that is a single character.
CodePudding user response:
It's is not so much the behavior of in
that's different, as the syntax being unexpected for beginners. ()
is an empty tuple. But that's the only time that parentheses make a tuple. In all other cases, parentheses are needed for grouping, but it's the comma that makes a tuple.
('aeiou')
is not a tuple. It's a string with superfluous parentheses.('aeiou',)
is a tuple, and so is'aeiou',
.['aeiou']
is unambiguously a list with one element.
Letters are length-one strings in python: there are no character objects as such.
- In the first case, you are searching for each letter in a string, which is a container of length-one strings, so you occasionally find one.
- In the second case, you are searching for each letter in a list, which is a container of not-length-one strings, so you never find a match.
Compare the second case to list('aeiou')
. Instead of making a list of one element as ['aeiou']
, this creates a list containing all the letters in the input string.
Unrelated fun fact: sum
defaults to a starting value of 0
(the int
), and bool
is a subclass of int
that always equals zero or one. You can therefore rewrite your counter in the following ways:
sum(letter in 'aeiou' for letter in sentence)
sum(map('aeiou'.__contains__, sentence))
CodePudding user response:
('aeiou')
equals 'aeiou'
, brackets like this are redundant.
Second time you are looking if chars from your sentence
are in ['aeiou']
. This list contains a string of 5 characters, so letter in ['aeiou']
would never return True
.