2016-07-22 6 views
0

ネストされたフィルタの仕組みを完全に理解していないと思います。ネストされたフィルタの仕組みは?

私は非常にネストされた(と少し愚かな)作成したフィルタオブジェクト:

L = iter(range(100000)) 

for i in range(10000): 
    L = filter(lambda x, i=i: x != i, L) 

追加のフィルタレベルはそれぞれ、ちょうど(実際には1つの項目で)いくつかのより多くのイテレータをトリミングします。

このフィルタオブジェクトを呼び出すと、すべてのネストされた条件が各next呼び出しでテストされると予想されました。 nextの値がこれらの条件をすべて正常に通過したことを他にどのように知ることができますか?実際、最初の呼び出しは実行に非常に長い時間がかかりますが、その後、各追加反復がかなり短いです:

import time 

j = 0 
lasttime = time.time() 
for x in L: 
    curtime = time.time() 
    print(x, curtime - lasttime) 
    lasttime = curtime 
    j += 1 
    if j > 10: 
     break 

結果は次のとおりです。

10000 9.558015823364258 
10001 0.0020017623901367188 
10002 0.002501964569091797 
10003 0.0020017623901367188 
10004 0.0025022029876708984 
10005 0.0025017261505126953 
10006 0.0020020008087158203 
10007 0.002001047134399414 
10008 0.002501249313354492 
10009 0.002002716064453125 
10010 0.0 

ボンネットの下に何が?これはどうですか?私はこれを作成する内側の作業についていくつかの説明を感謝します。

+0

これらの結果はpython2またはpython3ですか? – Alec

+2

ここではまったく予想外のことは何ですか?もちろん、最初の10000要素がすべて破棄された後、繰り返しがかなり長くかかるため、「最初の」値は実際は10001です。 –

+0

ちなみに、この深さのフィルタをネストすると、スタックオーバーフローが発生する可能性があります。それを避けるようにしてください。 – user2357112

答えて

2

最初の反復では、最初の10,000個の要素を拒否するために約5000万件の述語テストを適用する必要があります。それ以降のすべての反復では、次の要素を受け入れるために1万回のテストを適用するだけで済むので、5000倍も高速です。後の反復の間に見られる変化はノイズだけです。それは重要ではない。

+0

あなたは5000万人の人物について詳しく説明できますか? –

+0

@ juanpa.arrivillaga:最初の10000要素のそれぞれは、拒否される10000述語の約半分を通過する必要があります。 – user2357112

+0

ああ、最初の1万人の各要素が5000万回のテストを通過しなければならないと思った。 –