Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PEP 3106 suggests slower way? Why?

Recently, I had to convert the values of a dictionary to a list in Python 3.6 and an use case where this is supposed to happen a lot.
Trying to be a good guy I wanted to use a solution which is close to the PEP. Now, PEP 3106 suggests

list(d.keys())

which obviously works fine - but using timeit on my Windows 7 machine i see

>python -m timeit "[*{'a': 1, 'b': 2}.values()]"
1000000 loops, best of 3: 0.249 usec per loop

>python -m timeit "list({'a': 1, 'b': 2}.values())"
1000000 loops, best of 3: 0.362 usec per loop

I assume that there is an advantage in the latter version, because why else should the PEP suggest the slower one.

So here comes my question: What's the advantage of the latter version compared to the first one?

like image 702
d4tm4x Avatar asked Mar 20 '18 12:03

d4tm4x


1 Answers

The answer is because the faster syntax was first introduced in PEP 448 in 2013, while PEP 3106 you reference was written in 2006, so even if is faster in a real way now, it didn't exist when the PEP was written.

As noted by others, the role of PEPs is not to provide a template for the fastest possible code - in general, code in PEPs will aim to be simpler and as clear as possible, because examples are generally about understanding concepts rather than achieving the best possible results, so even if the syntax did exist at the time, and is faster in a real (and reliable) way, it still may not have been used.

A bit of further testing with larger values:

python -m timeit -s "x = [1]*10000" "[*x]"                
10000 loops, best of 3: 44.6 usec per loop

python -m timeit -s "x = [1]*10000" "list(x)" 
10000 loops, best of 3: 44.8 usec per loop

Shows the difference isn't really two times, but rather a flat cost - I would guess it's the cost of looking up the list() built-in function. This is negligible in most real cases.

like image 108
Gareth Latty Avatar answered Oct 01 '22 15:10

Gareth Latty