为何Python回文生成器仅每隔一个回文进入循环块?
生成器.send()导致循环跳过回文的原因分析
问题代码
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 return num == reversed_num pal_gen = infinite_palindromes() for e in pal_gen: digits = len(str(e)) pal_gen.send(10**(digits))
原因解析
核心冲突在于for循环的自动迭代逻辑和手动调用.send()的行为重叠:
- 生成器产出第一个回文
11后,进入for循环块,调用pal_gen.send(100)。此时.send()会把100传入生成器,将num设为100,随后num +=1变为101(符合回文条件)。 - 但
.send()方法的特性是:传入值后会触发生成器继续执行到下一个yield,并返回该yield产出的值——也就是101这个回文会被.send()直接返回,但for循环并未捕获这个返回值,导致它被丢弃。 - 当程序回到
for e in pal_gen:时,for循环会自动调用next(pal_gen),生成器从101之后继续执行,直到找到下一个回文111,才会把111赋值给e进入循环块。
这就造成了“每隔一个回文才执行循环块”的现象——那些被.send()产出但未被捕获的回文,都被跳过了。
修复示例
改用while循环手动控制迭代,捕获.send()返回的回文值:
pal_gen = infinite_palindromes() current = next(pal_gen) while current: print(current) digits = len(str(current)) current = pal_gen.send(10**digits)
内容的提问来源于stack exchange,提问作者DorderaDomo
相关产品推荐
相关产品推荐

