Являются ли списки Python такими же, как map / grep в Perl? - PullRequest
17 голосов
/ 14 сентября 2009

У меня были некоторые проблемы с синтаксисом понимания списков в Python, поэтому я начал думать о том, как добиться того же в Perl, с которым я более знаком. Я понял, что основные примеры (взятые из этой страницы ) могут быть выполнены в Perl с помощью map или grep.

1007 * Е.Г. *

(python)                            (perl)                  
S = [x**2 for x in range(10)]       @S = map { $_**2 } ( 0..9 );
V = [2**i for i in range(13)]       @V = map { 2**$_ } ( 0..12 );
M = [x for x in S if x % 2 == 0]    @M = grep { $_ % 2 == 0 } @S;

Значит, "понимание списка" - это просто причудливый термин для "отображения и / или фильтрации списка" или есть что-то еще?

Ответы [ 6 ]

14 голосов
/ 14 сентября 2009

Вы правы: понимание списка по сути является просто синтаксическим сахаром для карты и фильтра (термины из мира функционального программирования).

Надеюсь, этот пример кода демонстрирует их равенство:

>>> # Python 2
>>> [x**2 for x in range(10)] == map(lambda x: x**2, range(10))
True
>>> [2**i for i in range(13)] == map(lambda x: 2**x, range(13))
True
>>> S = [x**2 for x in range(10)]
>>> [x for x in S if x % 2 == 0] == filter(lambda x: x % 2 == 0, S)
True

Обратите внимание, что это допустимо только в Python 2.X, как указано в комментарии SilentGhost. Чтобы сделать это совместимым с Python 3, вам нужно обернуть вызовы map или filter в конструктор list, потому что map и filter были обновлены, чтобы возвращать итераторы, а не списки.

>>> # Python 3
>>> [x**2 for x in range(10)] == list(map(lambda x: x**2, range(10)))
True
>>> [2**i for i in range(13)] == list(map(lambda x: 2**x, range(13)))
True
>>> S = [x**2 for x in range(10)]
>>> [x for x in S if x % 2 == 0] == list(filter(lambda x: x % 2 == 0, S))
True
3 голосов
/ 14 сентября 2009

Да, они в основном одинаковы.

На самом деле Python также имеет функцию карты:

S = map(lambda x: x**2, range(10))

совпадает с вашими первыми примерами выше. Тем не менее, синтаксис понимания списка настоятельно рекомендуется в Python. Я полагаю, что Гвидо был процитирован, говоря, что он сожалеет о введении функционального синтаксиса вообще.

Однако, где это становится действительно интересным, в следующей эволюции понимания списка, которое является генераторами. Они позволяют вам возвращать итератор - вместо того, чтобы обрабатывать весь список сразу, он выполняет одну итерацию и затем возвращает, так что вам не нужно одновременно хранить весь список в памяти. Очень мощный.

2 голосов
/ 14 сентября 2009

Список понятий также выравнивает вещи:

Например:

[(x, y) для x в xrange (10), если x% 2 == 0 для y в xrange (20), если x! = Y]

Если вы использовали здесь вложенные карты, вам также пришлось бы использовать concat (суммирование списков).

2 голосов
/ 14 сентября 2009

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

[j for i in nested_list for j in i]

Еще одна вещь, которую вы не можете сделать с обычной картой и лямбда-выражением, - это структурное разложение итерирующих значений, например:

[(x%y)*z for x,y,z in list_with_triplets_of_ints]

конечно, есть обходные пути, такие как:

aux = lambda x,y,z: (x%y)*z
map(lambda t: aux(*t), list_with_triplets_of_ints)

но когда преобразование, которое вам нужно применить, уже определено, то обычно проще использовать карту, как в:

map(int, list_of_str_values)

вместо

[int(i) for i in list_of_str_values]
0 голосов
/ 14 сентября 2009

Да. Сила синтаксиса Python заключается в том, что тот же синтаксис (в круглых, а не в квадратных скобках) также используется для определения генераторов, которые создают последовательности значений по запросу.

0 голосов
/ 14 сентября 2009

Постижения списков являются более мощными, чем карта или фильтр, поскольку они позволяют вам абстрактно играть со списками.

Кроме того, их удобнее использовать, когда на ваши карты добавлено больше карт и фильтров вызовов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...