Это довольно странно, но я пытаюсь изучить / понять функциональное программирование на Python. Следующий код:
foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3]
def maptest(foo, bar):
print foo, bar
map(maptest, foos, bars)
производит:
1.0 1
2.0 2
3.0 3
4.0 None
5.0 None
В. Есть ли способ использовать карту или любые другие функциональные инструменты в Python для создания следующего без циклов и т. Д.
1.0 [1,2,3]
2.0 [1,2,3]
3.0 [1,2,3]
4.0 [1,2,3]
5.0 [1,2,3]
Просто в качестве примечания, как изменится реализация, если существует зависимость между foo и bar. например
foos = [1.0,2.0,3.0,4.0,5.0]
bars = [1,2,3,4,5]
и распечатать:
1.0 [2,3,4,5]
2.0 [1,3,4,5]
3.0 [1,2,4,5]
...
PS: Я знаю, как сделать это наивно, используя if, циклы и / или генераторы, но я хотел бы узнать, как добиться того же с помощью функциональных инструментов. Это просто случай добавления оператора if в maptest или применения другой карты фильтров к барам внутри maptest?
python
dictionary
functional-programming
eusoubrasileiro
источник
источник
Ответы:
Самый простой способ - не проходить
bars
через различные функции, а получить к ним доступ напрямую изmaptest
:С вашей исходной
maptest
функцией вы также можете использовать лямбда-функцию вmap
:источник
Вы знакомы с другими функциональными языками? т.е. вы пытаетесь узнать, как Python выполняет функциональное программирование, или вы пытаетесь узнать о функциональном программировании и использовании Python в качестве средства передвижения?
Кроме того, вы понимаете состав списков?
прямо эквивалентен (*):
На самом деле, я думаю, что
map()
когда-то планировалось удалить из python 3.0 как избыточный (этого не произошло).в основном эквивалентно:
(есть разница в том, как он обрабатывает случай, когда последовательности имеют разную длину. Как вы видели,
map()
заполняется None, когда одна из последовательностей заканчивается, тогда какzip()
останавливается, когда останавливается самая короткая последовательность)Итак, чтобы ответить на ваш конкретный вопрос, вы пытаетесь получить результат:
Вы можете сделать это, написав функцию, которая принимает единственный аргумент и печатает его, за которым следуют полосы:
В качестве альтернативы вы можете создать список, который будет выглядеть так:
и используйте свой исходный маптест:
Один из способов сделать это - заранее явно создать список:
Как вариант, вы можете вставить
itertools
модуль.itertools
содержит множество умных функций, которые помогут вам выполнять программирование с отложенным вычислением в функциональном стиле на Python. В данном случае мы хотимitertools.repeat
, чтобы аргумент выводился бесконечно при повторении по нему. Этот последний факт означает, что если вы это сделаете:вы получите бесконечный вывод, так как
map()
будет продолжаться до тех пор, пока один из аргументов все еще производит вывод. Тем не менее,itertools.imap
это то жеmap()
самое, но останавливается, как только останавливается самая короткая итерация.Надеюсь это поможет :-)
(*) В python 3.0 все немного по-другому. Там map () по существу возвращает выражение генератора.
источник
itertools.imap(f, sequence1, sequence2)
действительно эквивалентно[f(x1, x2) for x1, x2 in zip(sequence1, sequence2)]
?list(itertools.imap(f, sequence1, sequence2))
Вот решение, которое вы ищете:
Я бы рекомендовал использовать понимание списка (
[(x, bars) for x in foos]
часть) вместо использования карты, поскольку оно позволяет избежать накладных расходов на вызов функции на каждой итерации (что может быть очень значительным). Если вы просто собираетесь использовать его в цикле for, вы получите лучшую скорость, используя понимание генератора:Разница в том, что понимание генератора загружается лениво .
ОБНОВЛЕНИЕ В ответ на этот комментарий:
Я полагаю, это верная точка зрения. Я могу придумать два решения этой проблемы. Наиболее эффективным, вероятно, будет что-то вроде этого:
Поскольку кортежи неизменяемы, это предотвратит изменение полос в результате понимания этого списка (или понимания генератора, если вы пойдете по этому маршруту). Если вам действительно нужно изменить каждый из результатов, вы можете сделать это:
Однако это может быть немного дороже как с точки зрения использования памяти, так и с точки зрения скорости, поэтому я бы не рекомендовал его, если вам действительно не нужно добавлять к каждому из них.
источник
Функциональное программирование - это создание кода без побочных эффектов.
map - это абстракция функционального преобразования списка. Вы используете его, чтобы взять последовательность чего-то и превратить ее в последовательность чего-то еще.
Вы пытаетесь использовать его как итератор. Не делай этого. :)
Вот пример того, как вы можете использовать map для создания нужного списка. Есть более короткие решения (я бы просто использовал понимание), но это поможет вам понять, какая карта работает немного лучше:
Обратите внимание на то, что на этом этапе вы только манипулировали данными. Теперь его можно распечатать:
- Я не совсем понимаю, что вы имеете в виду под словом «без петель». fp - это не избежание циклов (вы не можете изучить каждый элемент в списке, не посещая каждый из них). Речь идет об избежании побочных эффектов, что позволяет писать меньше ошибок.
источник
источник
источник
Вот обзор параметров
map(function, *sequences)
функции:function
это имя вашей функции.sequences
- любое количество последовательностей, которые обычно представляют собой списки или кортежи.map
будет перебирать их одновременно и передавать текущие значенияfunction
. Поэтому количество последовательностей должно равняться количеству параметров вашей функции.Похоже, вы пытаетесь выполнить итерацию для некоторых
function
параметров, но сохранить другие постоянными, и, к сожалению,map
это не поддерживает. Я нашел старое предложение добавить такую функцию в Python, но конструкция карты настолько чиста и хорошо отработана, что я сомневаюсь, что что-то подобное когда-либо будет реализовано.Используйте обходной путь, например глобальные переменные или составление списков, как предлагали другие.
источник
Будет ли это делать?
источник
bar
подразумевает получение повторяющегося значения, когда вам действительно нужен весь список.Как насчет этого:
источник