This question arises when I read a generator tutorial https://realpython.com/introduction-to-python-generators/. is_palindrome(101)
returns True, but the code didn't print 101. I debugged and saw yield 101
led the execution back to the main for
loop, which immediately went back to the generator, which is very confusing. The generator yields 101, hence it should be an element of for j in pal_gen:
, isn't it?
def is_palindrome(num):
# Skip single-digit inputs
if num // 10 == 0:
return False
temp = num
reversed_num = 0
while temp != 0:
reversed_num = (reversed_num * 10) + (temp % 10)
temp = temp // 10
if num == reversed_num:
return True
else:
return False
def infinite_palindromes():
num = 0
while True:
if is_palindrome(num):
i = (yield num)
if i is not None:
num = i
num += 1
if __name__=='__main__':
pal_gen = infinite_palindromes()
for j in pal_gen:
print(f'j={j}')
digits = len(str(j))
if digits == 5:
pal_gen.close()
pal_gen.send(10 ** (digits))
Currently the output is:
j=11
j=111
j=1111
j=10101
Traceback (most recent call last):
File "generator.py", line 33, in <module>
pal_gen.send(10 ** (digits))
StopIteration
You'll notice it is skipping one between each. 101 is missing, 1001 is missing. 10001 is missing. I'm pretty sure send
leads the generator to run to the next yield statement. For example, use the following code:
if __name__=='__main__':
pal_gen = infinite_palindromes()
for j in pal_gen:
print('j={}'.format(j))
digits = len(str(j))
if digits == 5:
pal_gen.close()
print(pal_gen.send(10 ** (digits)))
This will print out the missing values between the "j's":
j=11
101
j=111
1001
j=1111
10001
j=10101
Consider redoing your for
statement with a while
:
if __name__=='__main__':
pal_gen = infinite_palindromes()
j=next(pal_gen)
digits=0
while digits<5:
print('j={}'.format(j))
digits = len(str(j))
j = pal_gen.send(10 ** (digits))
else:
pal_gen.close()