Create two lists at once

Background

The algorithm manipulates financial analytics. There are several lists of the same size, and they are filtered into other lists for analysis. I am doing the same filtering on different parallel lists. I could set it up so that a1, b1, c2 appear as a tuple in a list, but then analysts would need to cross out the tuples in a different way for analysis (regression of one list against another, beta, etc.).

What i want to do

I want to create two different lists based on the third list:

>>> a = list(range(10))
>>> b = list(range(10,20))
>>> c = list(i & 1 for i in range(10))
>>>
>>> aprime = [a1 for a1, c1 in zip(a,c) if c1 == 0]
>>> bprime = [b1 for b1, c1 in zip(b,c) if c1 == 0]
>>> aprime
[0, 2, 4, 6, 8]
>>> bprime
[10, 12, 14, 16, 18]

      

It seems like there should be a pythonic / functional programming / itertools ability to create two lists and iterate over three lists only once. Something like:

aprime, bprime = [a1, b1 for a1, b1, c1 in zip(a,b,c) if c1 == 0]

      

But of course this creates a syntax error.

Question

Is there a pythonic way?

Shootout with micro-optimization

An ugly but pythonic-to-max layout aligns the "just use for-loop" solution and my source code in the all-time popular timeit jail:

>>> import timeit
>>> timeit.timeit("z2(a,b,c)", "n=100;a = list(range(n)); b = list(range(10,10+n)); c = list(i & 1 for i in range(n));\ndef z2(a,b,c):\n\treturn zip(*[(a1,b1) for a1,b1,c1 in zip(a,b,c) if c1==0])\n")
26.977873025761482
>>> timeit.timeit("z2(a,b,c)", "n=100;a = list(range(n)); b = list(range(10,10+n)); c = list(i & 1 for i in range(n));\ndef z2(a,b,c):\n\taprime, bprime = [], [];\n\tfor a1, b1, c1 in zip(a, b, c):\n\t\tif c1 == 0:\n\t\t\taprime.append(a1);  bprime.append(b1);\n\treturn aprime, bprime\n")
32.232914169258947
>>> timeit.timeit("z2(a,b,c)", "n=100;a = list(range(n)); b = list(range(10,10+n)); c = list(i & 1 for i in range(n));\ndef z2(a,b,c):\n\treturn [a1 for a1, c1 in zip(a,c) if c1 == 0], [b1 for b1, c1 in zip(b,c) if c1 == 0]\n")
32.37302275847901

      

+2


source to share


3 answers


This might win an ugly code award, but it works in one line:



aprime, bprime = zip(*[(a1,b1) for a1,b1,c1 in zip(a,b,c) if c1==0])

      

+3


source


Just use a loop for

:



aprime = []
bprime = []
for a1, b1, c1 in zip(a, b, c):
    if c1 == 0:
        aprime.append(a1) 
        bprime.append(b1) 

      

+4


source


It is not possible to create multiple lists at the same time as a list - if you only want to iterate as soon as you need to do it in some other way - perhaps with a loop.

You can use list view to create a list of tuples, with the first element belonging to one list and the second to another. But if you want them to be separate lists, you still have to use a different operation to split it up.

0


source







All Articles