一次生成两个列表

时间:2009-08-31 20:21:03

标签: python

背景

该算法操纵财务分析。有多个相同大小的列表,它们被过滤到其他列表中进行分析。我在不同的并行列表上进行相同的过滤。我可以设置它以便a1,b1,c2作为列表中的元组出现但是然后分析必须以另一种方式对元组进行条带分析(一个列表与另一个列表的回归,beta等)。 / p>

我想做什么

我想基于第三个列表生成两个不同的列表:

>>> 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]

似乎应该有一个pythonic /函数编程/ itertools方法来创建两个列表并只迭代三个列表一次。类似的东西:

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

但当然这会产生语法错误。

问题

有没有pythonic方式?

微优化枪战

丑陋但pythonic到最大的单行边缘“只使用for-loop”解决方案和我在原始的 timeit 笼中的原始代码匹配:

>>> 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

3 个答案:

答案 0 :(得分:4)

只需使用for循环:

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

答案 1 :(得分:3)

这可能会赢得最丑陋的代码奖,但它可以在一行中使用:

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

答案 2 :(得分:0)

使用列表推导一次无法一次创建多个列表 - 如果您只想在需要时以其他方式进行迭代 - 可以使用循环进行迭代。

可以使用列表推导来创建元组列表,第一个元素属于一个列表,第二个元素属于另一个列表。但是如果你确实想要它们作为单独的列表,那么无论如何你将不得不使用另一个操作来拆分它。