1
A
回答
5
in
针对发电机表达将利用__iter__()
方法的和,直到找到一个匹配迭代的表达,使之更有效地在一般情况下比列表理解,它在扫描结果进行匹配之前首先产生整个列表。
您的具体示例的替代方法是使用any()
,以使测试更加明确。我觉得这是一个稍微更可读:
any(x[0] == 3 for x in l)
你必须要考虑到in
确实提出了发电机;如果您需要在其他地方使用发生器,则不能使用此方法。
至于你的具体时间测试;你的'短'测试是致命的缺陷。第一次迭代izip()
发电机将完全耗尽,使得其他9999次迭代测试与空的发电机测试。您正在测试创建一个空列表和一个空的生成器之间的差异,放大创建成本差异。
此外,您应该使用timeit
module来运行测试,确保测试是可重复。这意味着每次迭代都必须创建一个新的对象izip()
;现在对比度大得多:
>>> # Python 2, 'short'
...
>>> timeit.timeit("l = izip(xrange(10**2), xrange(10**2)); 3 not in (x[0] for x in l)", 'from itertools import izip', number=100000)
0.27606701850891113
>>> timeit.timeit("l = izip(xrange(10**2), xrange(10**2)); 3 not in [x[0] for x in l]", 'from itertools import izip', number=100000)
1.7422130107879639
>>> # Python 2, 'long'
...
>>> timeit.timeit("l = izip(xrange(10**3), xrange(10**3)); 3 not in (x[0] for x in l)", 'from itertools import izip', number=100000)
0.3002200126647949
>>> timeit.timeit("l = izip(xrange(10**3), xrange(10**3)); 3 not in [x[0] for x in l]", 'from itertools import izip', number=100000)
15.624258995056152
和Python的3:
>>> # Python 3, 'short'
...
>>> timeit.timeit("l = zip(range(10**2), range(10**2)); 3 not in (x[0] for x in l)", number=100000)
0.2624585109297186
>>> timeit.timeit("l = zip(range(10**2), range(10**2)); 3 not in [x[0] for x in l]", number=100000)
1.5555254180217162
>>> # Python 3, 'long'
...
>>> timeit.timeit("l = zip(range(10**3), range(10**3)); 3 not in (x[0] for x in l)", number=100000)
0.27222433499991894
>>> timeit.timeit("l = zip(range(10**3), range(10**3)); 3 not in [x[0] for x in l]", number=100000)
15.76974998600781
在所有情况下,发电机的变体是远远快;你要缩短“短”版本只是元组的列表解析开始赢:
>>> timeit.timeit("n = 8; l = izip(xrange(n), xrange(n)); 3 not in (x[0] for x in l)", 'from itertools import izip', number=100000)
0.2870941162109375
>>> timeit.timeit("n = 8; l = izip(xrange(n), xrange(n)); 3 not in [x[0] for x in l]", 'from itertools import izip', number=100000)
0.28503894805908203
在Python 3中,其中发电机表情和列表内涵的实现是更接近,你有下井4项的列表理解胜前:
>>> timeit.timeit("n = 4; l = zip(range(n), range(8)); 3 not in (x[0] for x in l)", number=100000)
0.284480107948184
>>> timeit.timeit("n = 4; l = zip(range(n), range(8)); 3 not in [x[0] for x in l]", number=100000)
0.23570425796788186
0
创建发电机比创建一个列表慢,所以你必须要考虑到的变量:时间用于创建对象和时间检验的表达。所以要回答你的问题,如果“更好”,你的意思是“更快”:这取决于n
。
0
在创建生成器表达式时存在一定的开销,但最终不需要分配大量内存来弥补它。
小列表解析速度较快,因为它们没有那个开销。
通常小的情况下足够接近,所以在这种情况下,最好选择一个生成器表达式
到一个网络服务器中可能有100的或1000的连接,同时节省内存,这是特别重要的。
相关问题
- 1. 列表理解vs生成器表达式的奇怪时间结果?
- 2. 字符串生成器vs列表
- 3. 列表生成器/阅读文件和列表的理解
- 4. 过滤器映射vs列表理解
- 5. 列表理解VS一套理解
- 6. Python:为什么列表理解会产生一个生成器?
- 7. 列表理解VS Enum.filter
- 8. 列表理解VS List.concat
- 9. symfony管理生成器外键列表
- 10. 管理生成器 - 列表操作
- 11. 在列表理解中创建多个生成器
- 12. Python生成器与列表理解冲突
- 13. Python - 此代码是否缺乏列表理解和生成器
- 14. 生成器陷入列表理解中的无限循环?
- 15. itertools.ifilter VS.过滤器VS.列表解析
- 16. 列表生成器
- 17. Hibernate生成器类增量vs序列?
- 18. WCF ChannelFactory vs生成代理
- 19. 理解列表vs for循环
- 20. python中嵌套列表理解和嵌套生成器表达式的顺序
- 21. Python生成器列表
- 22. 代码生成器vs ORM
- 23. 随机理解图表堆栈生成
- 24. Symfony管理生成器:将批处理操作从选择列表转换为使用管理生成器生成的对象列表中的链接
- 25. Python 2to3,有条件地迭代列表(过滤器vs列表理解)
- 26. ANTLR vs. Happy与其他解析器生成器
- 27. 理解列表[i-1] vs列表[i] -1
- 28. Python列表()vs列表理解构建速度
- 29. 生成没有列表理解的等效方法
- 30. 从列表理解输出中有效地生成numpy数组?
我会使用for循环,以便它不会构建整个列表,但它看起来很难看 – titus
您可以在发生器表达式中使用'in'。它只是消耗发电机到第一场比赛。 –
@gnibbler:ick,所以你可以; 'in'将会使用'__iter __()'来迭代,直到匹配。 –