Python中的'in'运算符是否具有"懒惰"特性?

4
如果我这样做,split()会在每次迭代中被调用吗?
a = [word for word in post.split() if len(word) > 10]

我应该这样做以获得更好的性能吗?
s = post.split()
a = [word for word in s if len(word) > 10]

6
“懒惰”并不是这个词的意思。 - vartec
@vartec,您介意再解释一下吗?还是这是一个完全不同的话题? - sooqua
3
那实际上并不是 in 运算符。这是列表推导式中的 for ... in ... 子句,尽管使用相同的关键字,但这并不完全相同。 - Blckknght
1
你应该这样做以获得更好的性能吗?你可以通过简单地尝试来回答这个问题。这个网站不是你的个人性能测试服务。 - TigerhawkT3
@sooqua https://zh.wikipedia.org/wiki/%E6%87%92%E6%95%A3%E8%AF%84%E4%BC%B0 - vartec
很遗憾这个标题是搜索结果中的首选,因为实际上了解一下in是否会强制评估整个迭代器会很有趣。 - LondonRob
2个回答

3

post.split() 只被调用了一次。你可以通过将 post.split() 替换为一个每次调用时都打印的函数来验证它:

>>> post = 'a b c d'
>>> def split_post():
...     print('split_post is called')
...     return post.split()
... 
>>> a = [word for word in split_post() if len(word) > 10]
split_post is called

你不需要将表达式分成两个语句以提高性能。

1
单个表达式很好——post.split()只会被调用一次。
这是因为Python中的for循环通过迭代支持迭代的对象的值来执行——它不会像在其他语言中遍历数组那样反复检查某个条件语句。
因此,在这种情况下,post.split()生成了您的对象,然后for循环对其进行迭代,无需再次调用。
"懒惰"-ness 在这里也不是正确的术语,因为它指的是延迟表达式评估直到严格需要的做法。在这里,我们肯定需要调用post.split(),问题更多是关于"效率"的问题。请参见维基百科上的惰性求值,了解该策略的良好描述。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接