2009-08-31 8 views
2

背景は一度

で二つのリストを生成するアルゴリズムは、財務分析を操作します。同じサイズの複数のリストがあり、分析のために他のリストにフィルタリングされます。私は、パラレルリストごとに異なるフィルタリングを行っています。私はa1、b1、c2がリスト内のタプルとして現れるように設定することができますが、分析はタプルを他の方法でストライプ化して分析を行います(他のリストに対してベータなどのリストを回帰させる)。私は3番目のリストに基づいて2つの異なるリストを生成したい

をやりたい

は:

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

作成するニシキヘビ/関数型プログラミング/ itertools方法があるはずと思われます2つのリストを繰り返し、3つのリストを1回だけ繰り返します。何かのように:

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

もちろん、これは構文エラーを生成します。

質問

は神託の方法はありますか?

マイクロ最適化戦

醜いが、ニシキヘビツー・マックスワンライナーは、今人気のはtimeitに解決し、私の元のコード「だけforループを使用する」アウトエッジケージマッチ:

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

なぜあなたは並行してリストを反復処理しようとしていますか?あなたが解決しようとしている全体的な問題は何ですか?おそらく、複数の並列リストを反復しようとするよりも簡単です。 –

+0

アルゴリズムは財務分析を操作します。同じサイズの複数のリストがあり、分析のために他のリストにフィルタリングされます。実際には、パラレルリストごとに異なるフィルタリングを行っています。私はa1、b1、c2がリスト内のタプルとして現れるように設定することができますが、分析はタプルを他の方法でストライプ化して分析を行います(他のリストに対してベータなどのリストを回帰させる)。 – hughdbrown

+0

aprimeとbprimeを作成するためのコードに問題がないとは思いません。どのような方法でそれが間違っているか不適切であるか? –

答えて

3

これは醜いコード賞を勝つかもしれないが、それは1行で動作します。

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

@ kaizer.se:このコメントはどういう意味ですか? – hughdbrown

+0

アスタリスクを使用している場合は、ジップを使用して解凍することは可能でしょうか? zip(* zip(a、b))== a、b – ACoolie

+0

zip - 解凍すると、Pythonイディオムのように感じられますが、最終的にはほとんど使用されないと思います。 forループがより明確になります。ところで、あなたはリストの理解の代わりにジェネレータの式を使うことができます(私はここでそれが重要であるとは確信していません)、リストが非常に長い場合はitertools.izipがあります。 – u0b34a0f6ae

0

リストの内包して一度に複数のリストを作成する方法はありません - ループで可能 - あなただけがそれにいくつかの他の方法を行うために必要になるだろう一度反復する場合。

はリスト内包を使用して、最初の要素が1つのリストに属し、2番目が1つのタプルのリストを作成します。しかし、別々のリストとしてそれらを使いたい場合は、とにかく別の操作を使用して分割する必要があります。

4

だけforループを使用します。

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