Possible to return two lists from a list comprehension?

Question:

Is it possible to return two lists from a list comprehension? Well, this obviously doesn’t work, but something like:

rr, tt = [i*10, i*12 for i in xrange(4)]

So rr and tt both are lists with the results from i*10 and i*12 respectively.
Many thanks

Asked By: LarsVegas

||

Answers:

>>> rr,tt = zip(*[(i*10, i*12) for i in xrange(4)])
>>> rr
(0, 10, 20, 30)
>>> tt
(0, 12, 24, 36)
Answered By: jamylak

It is possible for a list comprehension to return multiple lists if the elements are lists.
So for example:

>>> x, y = [[] for x in range(2)]
>>> x
[]
>>> y
[]
>>>

The trick with zip function would do the job, but actually is much more simpler and readable if you just collect the results in lists with a loop.

Answered By: Mariy

Creating two comprehensions list is better (at least for long lists). Be aware that, the best voted answer is slower can be even slower than traditional for loops. List comprehensions are faster and clearer.

python -m timeit -n 100 -s 'rr=[];tt = [];' 'for i in range(500000): rr.append(i*10);tt.append(i*12)' 
10 loops, best of 3: 123 msec per loop

> python -m timeit -n 100 'rr,tt = zip(*[(i*10, i*12) for i in range(500000)])' 
10 loops, best of 3: 170 msec per loop

> python -m timeit -n 100 'rr = [i*10 for i in range(500000)]; tt = [i*10 for i in range(500000)]' 
10 loops, best of 3: 68.5 msec per loop

It would be nice to see list comprehensionss supporting the creation of multiple lists at a time.

However,

if you can take an advantage of using a traditional loop (to be precise, intermediate calculations), then it is possible that you will be better of with a loop (or an iterator/generator using yield). Here is an example:

$ python3 -m timeit -n 100 -s 'rr=[];tt=[];' "for i in (range(1000) for x in range(10000)): tmp = list(i); rr.append(min(tmp));tt.append(max(tmp))" 
100 loops, best of 3: 314 msec per loop

$ python3 -m timeit -n 100 "rr=[min(list(i)) for i in (range(1000) for x in range(10000))];tt=[max(list(i)) for i in (range(1000) for x in range(10000))]"
100 loops, best of 3: 413 msec per loop

Of course, the comparison in these cases are unfair; in the example, the code and calculations are not equivalent because in the traditional loop a temporary result is stored (see tmp variable). So, the list comprehension is doing much more internal operations (it calculates the tmp variable twice!, yet it is only 25% slower).

Answered By: toto_tico
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.