【问题标题】:Calling any() on a generator with print() inside it produces unexpected behaviour在带有 print() 的生成器上调用 any() 会产生意外行为
【发布时间】:2017-10-04 20:45:42
【问题描述】:

any 一旦在任何可迭代对象(无论是迭代器、生成器、列表等)中找到单个真值,就应该短路

对于普通的生成器,这是真的:

Python 3.6.2 (v3.6.2:5fd33b5, Jul  8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32  
Type "help", "copyright", "credits" or "license" for more information.
>>> gen = (i for i in range(100))
>>> gen
<generator object <genexpr> at 0x0341A360>
>>> next(gen)
0                         
>>> next(gen)
1   
>>> any(gen)
True                                                                                       
>>> next(gen)
3                                      
>>>

如果您创建包含print 的生成,any 不会短路:

>>> gen = (print(i) for i in range(100))
>>> next(gen)
0
>>> next(gen)
1
>>> any(gen)
2
3
4
5
6
7
8
9
...

为什么添加print 可以防止any 短路?

【问题讨论】:

  • 因为print 返回None,这是一个虚假值。
  • 你期待会发生什么?

标签: python generator


【解决方案1】:

函数print() 返回None。考虑一下:

>>> gen = (print(i) for i in range(10))
>>> list(gen)
0
1
2
3
4
5
6
7
8
9
[None, None, None, None, None, None, None, None, None, None]

您可以看到生成器在每次迭代时都返回None

any() 一直运行直到找到一个真值。由于None 永远不会是真实的,所以any() 会一直运行到完成。

您可以通过确保生成器为每次迭代返回预期值来挽救您的原始代码:

>>> gen = (print(i) or i for i in range(10))
>>> next(gen)
0
0
>>> next(gen)
1
1
>>> any(gen)
2
True

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    • 1970-01-01
    • 2015-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多