2011-08-09 1 views
2

非常に大きな整列した整数リストを処理する最適な方法を探したい。 大きなリストから計算された値をpythonでフィルタリングして複数の小さなリストを作成する

biglist = [45, 34, 2, 78, 7, 9, 10, 33, 78, 51, 99, 24, 88, ... N] where N > 1m 

は、各BIGLIST要素を読み取ることにより固定長S(〜= 200)の複数の小さなリストを作成する要素に異なる動作を適用し、満たしている場合、条件付き基準要素又は各小リストに値を追加します例えばSに達するまで。

x_smallist = [] 
y_smallist = [] 
z_smallist = [] 
count = 0 
for i in biglist: 
    b = i/5 
    a = b * 2 
    c = a^3 + b 
    if b > 7 and b < 69: 
     x_smallist.append(i) 
     y_smallist.append(a) 
     z_smallist.append(b) 
     count += 1 
    if count > S: 
     break 

例と機能は説明のためだけのものです。ビッグリストが大きく、Sに達するまで各要素が読み込まれ、処理が何千回も繰り返されるので、私はforループを避けたい。リストの理解度(またはマップやフィルタ)でこれをどのように達成できますか?

+3

あなたが各要素にこれだけの処理を行っている場合は、A)あなたはリスト内包でそれを表現することはできませんと、b)、リストの内包表記の時間節約が本物で矮小化されますとにかくやる必要がある仕事。 –

+0

これは 'for'ループとして最もよく行われます。 list comprehensionsと 'filter'は' a'、 'b'、' count'のような中間変数を必要としないときのものです。より速くするための私の唯一の可能な提案は、 'smallist.append((i、a、b))'にタプルを追加する単一のリストを持つことです。 – agf

+0

は、リストを前もってフィルタリングするのは簡単ではないようです。 –

答えて

0

ジェネレータが各リストの新しい要素を持つタプルを生成し、次にzipを使用して必要な3つのリストを作成することによって、次のようにしてください。 biglistのイテレーターが最初に作成されるので、ループを通過するたびに中断したところからピックアップし、isliceが使用され、ジェネレーターがSエレメントで停止します。

itr = iter(biglist) 
while True: 
    lists = itertools.islice(((i, i/5*2, i/5) for i in itr if 7 < i/5 < 69), S) 
    x_smallist, y_smallist, z_smallist = zip(*lists) 
    if len(x_smallist) == 0: 
     break  # reached the end of biglist 
    # do stuff with your small lists 
+0

完全に動作します。ありがとうございました! –

0

biglistは本当にリストにする必要がありますか?ジェネレーターを使ってそれらを作成することができれば、メモリーを節約でき、時間を節約することができます。あなたが複数のチャンクをしたい場合

+0

biglistは任意の適切なデータ構造ですが、要素はあらかじめ計算され、順序付けされています。 –

0
S = 200 
import itertools 
biglist = itertools.islice(itertools.ifilter(lambda x: 7 < x/5 < 69, biglist),S) 

か、単に結果にifilterして、ループを適用します。

関連する問題