user1473483
user1473483

Reputation: 315

Two assignments in single python list comprehension

For example:

a = [1,2,3]
x = [2*i for i in a]
y = [3*i for i in a]

Would it be more efficient to combine the list comprehensions into one (if possible) if the size of a is large? If so, how do you do this?

Something like,

x,y = [2*i, 3*i for i in a]

which doesn't work. If using list comprehension is not more computationally efficient than using a normal for loop, let me know too. Thanks.

Upvotes: 7

Views: 3081

Answers (2)

Trufa
Trufa

Reputation: 40747

When in doubt about efficiency use the timeit module, it's always easy to use:

import timeit

def f1(aRange):
    x = [2*i for i in aRange]
    y = [3*i for i in aRange]
    return x,y

def f2(aRange):
    x, y = zip(*[(2*i, 3*i) for i in aRange])
    return x,y

def f3(aRange):
    x, y = zip(*((2*i, 3*i) for i in aRange))
    return x,y

def f4(aRange):
    x = []
    y = []
    for i in aRange:
        x.append(i*2)
        y.append(i*3)
    return x,y

print "f1: %f" %timeit.Timer("f1(range(100))", "from __main__ import f1").timeit(100000)
print "f2: %f" %timeit.Timer("f2(range(100))", "from __main__ import f2").timeit(100000)
print "f3: %f" %timeit.Timer("f3(range(100))", "from __main__ import f3").timeit(100000)
print "f4: %f" %timeit.Timer("f4(range(100))", "from __main__ import f4").timeit(100000)

The results seem to be consistent in pointing to the first option as the quickest.

f1: 2.127573
f2: 3.551838
f3: 3.859768
f4: 4.282406

Upvotes: 10

Gareth Latty
Gareth Latty

Reputation: 89097

You want to use the zip() builtin with the star operator to do this. zip() normally turns to lists into a list of pairs, when used like this, it unzips - taking a list of pairs and splitting into two lists.

>>> a = [1, 2, 3]
>>> x, y = zip(*[(2*i, 3*i) for i in a])
>>> x
(2, 4, 6)
>>> y
(3, 6, 9)

Note that I'm not sure this is really any more efficient in a way that is going to matter.

Upvotes: 13

Related Questions