背景
该算法操纵财务分析。有多个相同大小的列表,将它们过滤到其他列表中进行分析。我正在对不同的并行列表进行相同的过滤。我可以对其进行设置,以便 a1、b1、c2 作为列表中的元组出现,但随后分析必须以另一种方式对元组进行条带化以进行分析(一个列表相对于另一个列表的回归、β 等)。
我想做的事
我想根据第三个列表生成两个不同的列表:
>>> 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]
Run Code Online (Sandbox Code Playgroud)
似乎应该有一种 pythonic/函数式编程/itertools 方法来创建两个列表并仅迭代三个列表一次。就像是:
aprime, bprime = [a1, b1 for a1, b1, c1 in zip(a,b,c) if c1 == 0]
Run Code Online (Sandbox Code Playgroud)
但这当然会产生语法错误。
问题
有蟒蛇式的方法吗?
微观优化枪战
丑陋但Pythonic-to-the-max单行边缘边缘“只使用for循环”解决方案和我的原始代码在流行的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
Run Code Online (Sandbox Code Playgroud)
这可能会赢得最丑代码奖,但它只用一行代码就可以工作:
aprime, bprime = zip(*[(a1,b1) for a1,b1,c1 in zip(a,b,c) if c1==0])
Run Code Online (Sandbox Code Playgroud)