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 __()'來迭代,直到匹配。 –