Порядок аргументов функций фильтра Python

Python's filter и функции itertools.ifilter имеют следующие подписи:

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

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

1 ответ

Решение

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

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

filterТип подписи отражает ее происхождение и отсутствие встроенного каррирования в Python. Вы можете смоделировать это, используя 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)
Другие вопросы по тегам