2015-12-22 3 views
2

filter и itertools.ifilter функции Python имеет следующие подписи:языка Python заказать

filter(function, iterable) 
itertools.ifilter(predicate, iterable) 

Есть ли какая-либо причина, чтобы поместить predicate аргумент перед тем iterable? В этом случае нельзя пропустить аргумент predicate, чтобы упростить filter(bool, [0, 1, 0, 2]) звонок только filter([0, 1, 0, 2]). Второй для меня выглядит более идиоматично.

+1

Второй не имеет никакого смысла. Фильтрация списка без предиката? Как это будет работать? Помните, что явный лучше, чем неявный ('import this'). –

+2

@VincentSavard: Как ни странно, на самом деле существует определенное поведение для фильтрации без предиката. Если вы передадите 'None' в качестве предиката, он будет работать так же, как передача' bool' или 'lambda x: x'. – user2357112

+0

@ user2357112: Eww, это неутешительно. Спасибо за информацию. –

ответ

4

Это помогает понять парадигму, из которой был заимствован filter. Вместо того, чтобы думать о filter как функции, которая принимает функцию и список как два аргумента, подумайте об этом как о функции, которая принимает один аргумент - предикат. Возвращаемое значение - это функция , которая принимает список и возвращает новый список. В этом смысле filter - функция (действительно, функтор), которая «поднимает» функцию в новую «категорию».

Например, предположим, что у вас есть предикат is_even, который принимает целое число в качестве аргумента и возвращает true, если аргумент четный, false, если он нечетный. Тогда filter(is_even) можно рассматривать как возвращающее функцию, которая принимает список целых чисел и возвращает список из булевых элементов, каждый элемент указывает на четность соответствующего элемента ввода. Вы можете применить эту функцию к списку, так что filter(is_even)(list_of_ints) идентичен filter(is_even, list_of_ints) в Python. Этот метод разложения многоаргументной функции в ряд функций с одним аргументом называется currying.

filter Подпись типа отражает ее происхождение и отсутствие у Питона встроенного каррирования. Вы можете имитировать это с помощью functools.partial, что позволяет частично применить функцию, предоставив аргументы слева направо для определенных параметров.

from functools import partial 
x = partial(filter, is_even) # lambda lst: filter(is_even, lst) 
new_list = x(list_of_ints) 
# or just new_list = partial(filter, is_even)(list_of_ints) 
Смежные вопросы