To explain my query I have a simple code snippet below followed by my question.
def count_vowels(s):
num_vowels = 0
for char in s:
if char in 'aeiouAEIOU':
num_vowels = num_vowels + 1
return num_vowels
print(count_vowels(""))
print("" in "aeiouAEIOU")
gives an output
0
True
My doubt:
Why does an empty string "" returns True for the expression
"" in "aeiouAEIOU"
But it skips when it is present along with a for loop?
for char in s:
My understanding is that empty strings are a subset of all strings then why it is ignored when the same expression is in the for loop? Feel free to correct me if there is something I am missing here.
Your understanding is correct: "empty strings are a subset of all strings"
But now let's see what happens when we use for for a sequence type such as string. Let's say we have:
lst = [1, 2, 3, 4, 5]
for i in lst:
print(i ** 2)
You can just think that it turns into:
index = 0
while True:
try:
i = lst.__getitem__(index)
except IndexError:
break
print(i ** 2)
index += 1
In your Example, when it tries to get even the first item, it will raise an Exception and break out of the loop. So it doesn't even go inside For loop.
I said "just think" because in for-loop, iter() is get called on the object (here lst) and this built-in function will get an iterator out of the object. In order this to be happened the object should implement either the iterable protocol which is either __iter__ or it must support the sequence protocol (the __getitem__())).
lst = [1, 2, 3, 4, 5]
it = iter(lst)
while True:
try:
i = next(it)
except StopIteration:
break
else:
print(i ** 2)
Both str and list object have __iter__ so that is the method gets called rather than __getitem__. (__iter__ has precedence over __getitem__)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With