Python: может ли быть преобразован в списки, такие как map, lambda и filter?
При программировании на python я теперь избегаю map
, lambda
и filter
с помощью использования списков, потому что его легче читать и быстрее выполнять. Но может ли быть заменен reduce
?
например. объект имеет оператор union()
, который работает с другим объектом, a1.union(a2)
, и дает третий объект того же типа.
У меня есть список объектов:
L = [a1, a2, a3, ...]
Как иметь объединение() всех этих объектов со списком, эквивалентное:
result = reduce(lambda a, b :a.union(b), L[1:], L[0])
Ответы
Ответ 1
Не секрет, что сокращение не относится к привилегированным функциям Pythonistas.
В общем случае reduce является левым сгибом в списке
Концептуально легко написать складку в Python, которая будет складываться влево или вправо на итерабельном:
def fold(func, iterable, initial=None, reverse=False):
x=initial
if reverse:
iterable=reversed(iterable)
for e in iterable:
x=func(x,e) if x is not None else e
return x
Без какого-либо жестокого взлома это не может быть реплицировано в понимании, потому что в понимании нет функции типа аккумулятора.
Просто используйте сокращение - или напишите, что имеет больше смысла для вас.
Ответ 2
Не совсем. Перечисления списков больше похожи на map
и, возможно, filter
.
Ответ 3
Поскольку представление списка определяет, как генерирует другой список, вы не можете использовать его для создания одного значения. Не для этого. (Ну... есть этот неприятный трюк, который использует пропущенную деталь реализации в старых версиях python, которые могут это сделать. Я даже не собираюсь копировать пример код здесь. Не делайте этого.)
Если вы беспокоитесь о стилистических аспектах reduce()
и его иже, не будьте. Назовите свои сокращения, и все будет хорошо. Итак, пока:
all_union = reduce(lambda a, b: a.union(b), L[1:], L[0])
невелика, это:
def full_union(input):
""" Compute the union of a list of sets """
return reduce(lambda a, b: a.union(b), input[1:], input[0])
result = full_union(L)
довольно ясно.
Если вы беспокоитесь о скорости, посмотрите toolz и cytoolz, которые являются "быстрыми" и "безумно быстрыми" соответственно. В больших наборах данных они часто позволяют вам не обрабатывать ваши данные более одного раза или сразу загружать весь набор в память, в отличие от списков.
Ответ 4
Общее использование сокращения - это сглаживание списка списков. Вместо этого вы можете использовать понимание списка.
L = [[1, 2, 3], [2, 3, 4], [3, 4, 5]]
с уменьшением
from functools import reduce # python 3
flattened = reduce(lambda x, y: x + y, L)
print(flattened)
[1, 2, 3, 2, 3, 4, 3, 4, 5]
со списком comp
flattened = [item for sublist in L for item in sublist]
print(flattened)
[1, 2, 3, 2, 3, 4, 3, 4, 5]
Если ваша проблема может быть решена путем работы в сплющенном списке, это эффективная замена. Контрастность этих однострочных линий для данного примера:
all_union = reduce(lambda a, b: set(a).union(set(b)), L)
{1, 2, 3, 4, 5}
all_union = set([item for sublist in L for item in sublist])
{1, 2, 3, 4, 5}