简体   繁体   English

Python 生成器令人困惑的行为

[英]Python generator confusing behavior

This question arises when I read a generator tutorial https://realpython.com/introduction-to-python-generators/ .当我阅读生成器教程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. is_palindrome(101)返回True,但是代码并没有打印101。我调试了一下,看到yield 101导致执行回到main for循环,然后立即返回到generator,非常混乱。 The generator yields 101, hence it should be an element of for j in pal_gen: , isn't it?生成器产生 101,因此它应该是for j in pal_gen: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))

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. 101不见了,1001不见了。 10001 is missing. 10001 丢失。 I'm pretty sure send leads the generator to run to the next yield statement.我很确定send会导致生成器运行到下一个 yield 语句。 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”之间的缺失值:

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

Consider redoing your for statement with a while :考虑用一段while重做你的for语句:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM