0

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

1 Answer 1

1

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()
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. stackabuse.com/python-generators also says send() also consumes one value, when used without parameter, send() is actually equivalent to next().

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.