HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Are these list-comprehensions written the fastest possible way?

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thesewrittenthearewaycomprehensionspossiblefastestlist

Problem

This is a simple repeatable question regarding the usage of Python3's comprehensions:

Could the Python3 syntax be used in another way to speed up the process, further so the gap between Python3 and numpy would be reduced? (see chart below).

The results & code:

Above: Runtime test of Python3's list comprehension, dict comprehension, python for loop and numpy

Update 1 Above: Runtime test without power-functions including Janne Karila suggestion to break down the power function to x x x

Update2 Above: Runtime test without powerfunctions and with Justin Peels recommendation to use return list(a.values())

```
#/usr/bin/python3 -

import sys
from datetime import datetime
import numpy
import matplotlib.pyplot as pyplot

def doingnothing(n):
for i in range(n):
pass
return []

def numpysum(n): #NPY
a = numpy.arange(n) ** 2.
b = numpy.arange(n) ** 3.
c = a + b
return c

def listexpression(n): #LE
#return [x2+x3 for x in range(n)]
return [xx+xx*x for x in range(n)]

def dictcomprehension(n): #DC
# a = {x:x2+x3 for x in range(n)}
a = {x:xx+xx*x for x in range(n)}
# return [a[key] for key in a]
return list(a.values())

def pythonsum(n): #PS
a = list(range(n))
b = list(range(n))
c = []

for i in range(len(a)):
# a[i] = i ** 2.
a[i] = i * i
# b[i] = i ** 3.
b[i] = i i i
c.append(a[i] + b[i])
return c

def runtimetest(size,verbose=True):
v = verbose
d = {'DoingNothing':None,
'NPY':None,
'LE':None,
'DC':None,
'PS':None}

start = datetime.now()
c = doingnothing(size)
d['DoingNothing'] = datetime.now() - start

start = datetime.now()
c = numpysum(size)
d['NPY'] = datetime.now() - start

start = datetime.now()
c = listexpression(size)
d['LE'] = datetime.now() - start

start = datetime.now()
c = dictcomprehension(size)
d['DC'] = datet

Solution

def listexpression(n):  #LE
    return [x * x * (1 + x) for x in range(n)]


is over 3 times faster than your version with x2+x3 (from 8.47 ms to 2.31 ms with n = 10000).

Though, NumPy will also benefit from regrouping the expression this way.

Code Snippets

def listexpression(n):  #LE
    return [x * x * (1 + x) for x in range(n)]

Context

StackExchange Code Review Q#23441, answer score: 5

Revisions (0)

No revisions yet.