繁体   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