Python生成器令人困惑的行为

问题描述 投票:0回答:1

当我阅读发电机教程https://realpython.com/introduction-to-python-generators/时会出现此问题。 is_palindrome(101)返回True,但是代码未打印101。我调试并看到yield 101将执行返回到主for循环,该循环立即返回到生成器,这非常令人困惑。生成器的产量为101,因此应该为for j in pal_gen:的元素,不是吗?

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))

当前输出为:

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
python generator send coroutine
1个回答
0
投票

您会注意到它在每个之间都跳过了一个。缺少101,缺少1001。缺少10001。我很确定send使生成器运行到下一个yield语句。例如,使用以下代码:

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)))

这将打印出“ j”之间的缺失值:

j=11
101
j=111
1001
j=1111
10001
j=10101

考虑使用for重做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()
© www.soinside.com 2019 - 2024. All rights reserved.