Действительно ли понимания списка Python являются тем же самым как map/grep в Perl?

Можно найти некоторый материал об инструментах для веб-приложений Lisp в этот вопрос .

Это могло бы также стоить послушать Подкаст Переполнения стека 27 , где парни Reddit говорят немного об их опыте runnig веб-сайт на Lisp (и их переключатель к Python).

18
задан friedo 13 September 2009 в 21:41
поделиться

6 ответов

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

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

>>> # 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
14
ответ дан 30 November 2019 в 08:48
поделиться

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

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

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

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

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

3
ответ дан 30 November 2019 в 08:48
поделиться

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

[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]
3
ответ дан 30 November 2019 в 08:48
поделиться

Понимание списков также выравнивает вещи:

Например:

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

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

2
ответ дан 30 November 2019 в 08:48
поделиться

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

0
ответ дан 30 November 2019 в 08:48
поделиться

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

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

0
ответ дан 30 November 2019 в 08:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: