简体   繁体   English

For Loop Enumerate vs dict on enumerate

[英]For Loop Enumerate vs dict on enumerate

Let me preface this question by stating that I am a novice both in Python and programming in general.让我先声明我在 Python 和一般编程方面都是新手。 That said, I was wondering whether there is any difference between the following two ways of creating a dictionary based on an existing list:也就是说,我想知道以下两种基于现有列表创建字典的方法之间是否有任何区别:

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

Output: Output:

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

Both "print (index)" and "print (dict (enumerate (seq)" yield an equivalent result and I was wondering which one is better to perform in this context. I stumbled upon the latter by just practicing some coding and it made me question why one would need to perform a for loop if a one-line code such as the dict() gives the same result. “print(index)”和“print(dict(enumerate(seq)”)都产生了等效的结果,我想知道在这种情况下哪个更好。我通过练习一些编码偶然发现了后者,这让我质疑如果像 dict() 这样的单行代码给出相同的结果,为什么需要执行 for 循环。

I've seen a lot of one line loops.我见过很多单行循环。 It's just used as maybe a more compiled way of defining something but a for loop is just as good in most situations.它只是用作定义某些东西的更编译的方式,但在大多数情况下,for 循环同样好。

There is no semantic difference.没有语义差异。 This这个

dict(enumerate(seq))

will execute faster.将执行得更快。

Update: well, it seems that faster might not be as clear cut as I expected.. (or correct, except maybe for 3.9b1 - see @Bharel's answer).更新:好吧,似乎更快可能不像我预期的那样明确..(或正确的,可能除了 3.9b1 - 请参阅@Bharel 的答案)。

Update2: I've added measurements for the dict comprehension solution from @ShadowRanger for completeness.更新 2 为了完整性,我添加了来自 @ShadowRanger 的 dict 理解解决方案的测量。

Py2.7: 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: 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: 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

Update 3: @Bharel and @ShadowRanger has pointed out, the length of the list is important.更新 3: @Bharel 和 @ShadowRanger 指出,列表的长度很重要。 With lists of ~10 items, the dict(enumerate(..)) version becomes more performant.对于大约 10 个项目的列表, dict(enumerate(..))版本变得更加高效。

code:代码:

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: 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

There's no difference at all in the output. output 完全没有区别。

Regarding timing, you may use the timeit module to test for speed.关于计时,您可以使用timeit模块来测试速度。

The second option, of one lining will necessarily be faster, and is also more readable in my opinion.第二个选项,一个衬里必然会更快,并且在我看来也更具可读性。

Timing results, Python 3.9:时序结果,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

You might not see the difference in here, because the dict() operation for dict creation is longer than {} , and it's a fixed "setup cost".您可能看不到这里的区别,因为用于创建 dict 的dict()操作比{}长,而且它是一个固定的“设置成本”。

If you'll increase the numbers to offset this "setup cost", you'll see the huge difference:如果你增加数字来抵消这个“设置成本”,你会看到巨大的差异:

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)) is strictly better on performance and simplicity, it's just less flexible. dict(enumerate(seq))在性能和简单性方面确实更好,只是灵活性较差。 For more flexibility, you'd go with dict comprehensions typically, eg:为了获得更大的灵活性,您通常会使用 go 与dict理解,例如:

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

only going to your original for loop when the conversion code is too complicated for a comprehension.仅当转换代码太复杂而无法理解时才进入原始for循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM