簡體   English   中英

For Loop Enumerate vs dict on enumerate

[英]For Loop Enumerate vs dict on enumerate

讓我先聲明我在 Python 和一般編程方面都是新手。 也就是說,我想知道以下兩種基於現有列表創建字典的方法之間是否有任何區別:

index = {}
seq = ['a', 'b', 'c']
for a,b in enumerate(seq): 
    index[a]= b
print(index)
print(dict(enumerate(seq)))

Output:

>>> print(index)
{0: 'a', 1: 'b', 2: 'c'}
>>> print(dict(enumerate(seq)))
{0: 'a', 1: 'b', 2: 'c'}

“print(index)”和“print(dict(enumerate(seq)”)都產生了等效的結果,我想知道在這種情況下哪個更好。我通過練習一些編碼偶然發現了后者,這讓我質疑如果像 dict() 這樣的單行代碼給出相同的結果,為什么需要執行 for 循環。

我見過很多單行循環。 它只是用作定義某些東西的更編譯的方式,但在大多數情況下,for 循環同樣好。

沒有語義差異。 這個

dict(enumerate(seq))

將執行得更快。

更新:好吧,似乎更快可能不像我預期的那樣明確..(或正確的,可能除了 3.9b1 - 請參閱@Bharel 的答案)。

更新 2 為了完整性,我添加了來自 @ShadowRanger 的 dict 理解解決方案的測量。

Py2.7:

(dev) c:\srv> python -m timeit -s "seq = ['a', 'b', 'c']" "dict(enumerate(seq))"
1000000 loops, best of 3: 1.06 usec per loop

(dev) c:\srv> python -m timeit -s "seq = ['a', 'b', 'c']" "index = {}" "for a,b in enumerate(seq):" "  index[a]= b"
1000000 loops, best of 3: 0.686 usec per loop

(dev) c:\srv> python -m timeit -s "seq = ['a', 'b', 'c']" "{a: b for a,b in enumerate(seq)}"
1000000 loops, best of 3: 0.807 usec per loop

Py3.5:

(dev35) c:\srv> python -m timeit -s "seq = ['a', 'b', 'c']" "dict(enumerate(seq))"
1000000 loops, best of 3: 1.19 usec per loop

(dev35) c:\srv> python -m timeit -s "seq = ['a', 'b', 'c']" "index = {}" "for a,b in enumerate(seq):" "  index[a]= b"
1000000 loops, best of 3: 0.813 usec per loop

(dev35) c:\srv> python -m timeit -s "seq = ['a', 'b', 'c']" "{a: b for a,b in enumerate(seq)}"
1000000 loops, best of 3: 0.917 usec per loop

Py3.8:

(dev38) c:\srv> python -m timeit -s "seq = ['a', 'b', 'c']" "dict(enumerate(seq))"
500000 loops, best of 5: 755 nsec per loop

(dev38) c:\srv> python -m timeit -s "seq = ['a', 'b', 'c']" "index = {}" "for a,b in enumerate(seq):" "  index[a]= b"
500000 loops, best of 5: 703 nsec per loop

(dev38) c:\srv> python -m timeit -s "seq = ['a', 'b', 'c']" "{a: b for a,b in enumerate(seq)}"
500000 loops, best of 5: 879 nsec per loop

更新 3: @Bharel 和 @ShadowRanger 指出,列表的長度很重要。 對於大約 10 個項目的列表, dict(enumerate(..))版本變得更加高效。

代碼:

call workon dev
python -m timeit -s "seq = 'abcdefghij'" "dict(enumerate(seq))"
python -m timeit -s "seq = 'abcdefghij'" "index = {}" "for a,b in enumerate(seq):" "  index[a]= b"

call workon dev35
python -m timeit -s "seq = 'abcdefghij'" "dict(enumerate(seq))"
python -m timeit -s "seq = 'abcdefghij'" "index = {}" "for a,b in enumerate(seq):" "  index[a]= b"

call workon dev38
python -m timeit -s "seq = 'abcdefghij'" "dict(enumerate(seq))"
python -m timeit -s "seq = 'abcdefghij'" "index = {}" "for a,b in enumerate(seq):" "  index[a]= b"

output:

100000 loops, best of 3: 1.94 usec per loop
1000000 loops, best of 3: 1.9 usec per loop

1000000 loops, best of 3: 1.7 usec per loop
1000000 loops, best of 3: 1.6 usec per loop

200000 loops, best of 5: 1.29 usec per loop
200000 loops, best of 5: 1.66 usec per loop

output 完全沒有區別。

關於計時,您可以使用timeit模塊來測試速度。

第二個選項,一個襯里必然會更快,並且在我看來也更具可讀性。

時序結果,Python 3.9:

python -m timeit -s "seq = ['a', 'b', 'c']" "index = {}" "for a,b in enumerate(seq):" "  index[a]= b"
500000 loops, best of 5: 803 nsec per loop

python -m timeit -s "seq = ['a', 'b', 'c']" "dict(enumerate(seq))"
500000 loops, best of 5: 786 nsec per loop

您可能看不到這里的區別,因為用於創建 dict 的dict()操作比{}長,而且它是一個固定的“設置成本”。

如果你增加數字來抵消這個“設置成本”,你會看到巨大的差異:

python -m timeit -s "seq = ['a', 'b', 'c']*1000" "dict(enumerate(seq))"
500 loops, best of 5: 395 usec per loop

python -m timeit -s "seq = ['a', 'b', 'c']*1000" "index = {}" "for a,b in enumerate(seq):" "  index[a]= b"
500 loops, best of 5: 509 usec per loop

dict(enumerate(seq))在性能和簡單性方面確實更好,只是靈活性較差。 為了獲得更大的靈活性,您通常會使用 go 與dict理解,例如:

index = {i: x * 2 for i, x in enumerate(seq)}  # Repeats each value

僅當轉換代碼太復雜而無法理解時才進入原始for循環。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM