itertools.ifilter Vs. фильтр против список пониманий
Я пытаюсь стать более знакомым с itertools
модуль и нашли функцию под названием ifilter
,
Из того, что я понимаю, он фильтрует и повторяет на основе заданной функции и возвращает итератор по списку, содержащему элементы итерируемого, для которого функция оценивает: True
,
Вопрос 1: правильно ли мое понимание до сих пор?
Вопрос 2: кроме того, что это возвращает итератор, чем он отличается от встроенного filter
функционировать?
Вопрос 3 Что быстрее?
Из того, что я могу сказать, это не так. Я что-то пропустил? (Я провел следующий тест)
>>> itertools.ifilter(lambda x: x%2, range(5))
<itertools.ifilter object at 0x7fb1a101b210>
>>> for i in itertools.ifilter(lambda x: x%2, range(5)): print i
...
1
3
>>> filter(lambda x: x%2, range(5))
[1, 3]
>>> function = lambda x: x%2
>>> [item for item in range(5) if function(item)]
[1,3]
4 ответа
Пример ниже включает в себя генератор чисел, который печатает сообщение непосредственно перед выдачей числа, показывает, как filter()
сначала строит список, затем проходит через него и фильтрует его. В то время как itertools.ifilter
Фильтры как таковые, никогда не создавая список. Если вы фильтруете 500 000 значимых вещей, вы хотите ifilter
так что вы не строите список.
import itertools
def number_generator():
for i in range(0, 3):
print "yield", i
yield i
print "stopping"
function = lambda x: x > 0
numbers = number_generator()
print "itertools.ifilter:"
for n in itertools.ifilter(function, numbers):
print n
print "\nfilter:"
numbers = number_generator()
for n in filter(function, numbers):
print n
Выход:
itertools.ifilter: доходность 0 доходность 1 1 доходность 2 2 остановка фильтр: доходность 0 доходность 1 доходность 2 остановка 1 2
Ваше понимание верно: единственная разница в том, что ifilter
возвращает итератор при использовании filter
это как звонить:
list(ifilter(...))
Вы также можете быть заинтересованы в том, что говорит PEP 289 о фильтрах и фильтрах:
Понимание списка значительно уменьшило потребность в
filter()
а такжеmap()
, Аналогично, ожидается, что выражения-генераторы минимизируют необходимостьitertools.ifilter()
а такжеitertools.imap()
, [...]
Также обратите внимание, что ifilter
стал filter
в Python-3 (следовательно, удален из itertools).
ifilter
возвращает генератор, а не список.
Генераторы создают свои элементы на лету, когда это необходимо, вместо того, чтобы сначала распределять весь список. Это единственная разница между ifilter
а также filter
Здесь вы можете увидеть разницу:
фильтр (функция, итерируемая): построить список из тех элементов итерируемой, для которых функция возвращает true.
itertools.ifilter (предикат, итерируемый): создайте итератор, который отфильтровывает элементы от итерируемого, возвращая только те, для которых предикат равен True
Это означает, что для получения "ifiltered" элементов вы должны выполнять итерацию с возвращенным итератором, но "filter" возвращает все элементы в списке без необходимой итерации.