I was looking into this article by RealPython about Python generators. It uses a palindrome generator as a exemplary tool to explain the .send, .throw and .close methods. Building a program following their instructions gives the following code:
def infinite_palindromes():
    num = 0
    while True:
        if is_palindrome(num):
            i = (yield num)
            if i is not None:
                num = i
        num += 1
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
pal_gen = infinite_palindromes()
for e in pal_gen:
    digits = len(str(e))
    pal_gen.send(10**(digits))
I watched the flow of the program in debugging and what happens is basically, when the function finds 11, the first palindrome, it enters into the for e loop block, the digits variable is defined, and 10 to the power of that variable value is sent back to the generator. 100 is sent back, and since it is different from None, num is equated to i and becomes 100, then it's summed with 1 and becomes 101, the next palindrome. Here is what I don't get: when that number is throw and correctly identified as a palindrome, the code goes back to the for e in pal_gen: line, but it doesn't enter the block. Only the next palindrome, 111 is sent back down and enters the block, where the digits variable is defined again, and so on and so forth, and this patterns repeats, with only every other palindrome entering the block. Why is that?
Can someone, please, explain to me why that happens?
 
    