2016-07-22 8 views
0

Я думаю, я не совсем понимаю, как работают вложенные фильтры.Как работают вложенные фильтры?

Я создал весьма вложенный (и немного глупо) фильтр объект:

L = iter(range(100000)) 

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

Каждые из дополнительного уровня фильтра просто обрезать итератор несколько больше (на самом деле на один элемент).

Теперь, когда я вызываю этот объект фильтра, я ожидал, что все вложенные условия будут проверяться с каждым вызовом 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 элементов будут отброшены, поэтому «первое» значение будет фактически 10001st. –

+0

Кстати, вложенные фильтры этой глубины могут вызвать переполнение стека. Старайтесь избегать этого. – user2357112

ответ

2

Первая итерация должна применить около 50 миллионов тестов предиката, чтобы отклонить первые 10 тысяч элементов, поэтому требуется возраст. Каждая итерация после этого требует всего 10 тысяч тестов для принятия следующего элемента, поэтому они примерно в 5000 раз быстрее. Вариант, который вы видите между более поздними итерациями, - это просто шум; это не важно.

+0

Можете ли вы рассказать о 50-миллионной фигуре? –

+0

@ juanpa.arrivillaga: В среднем каждый из первых 10000 элементов должен пройти примерно половину из 10000 предикатов, которые должны быть отклонены. – user2357112

+0

Ах да, я думал, вы имели в виду, что каждый элемент в первых 10 тысячах должен был пройти 50 миллионов тестов. –

Смежные вопросы