Понимание функции карты
map(function, iterable, ...)
Применить функцию к каждому элементу итерации и вернуть список результатов. Если передаются дополнительные повторяющиеся аргументы, функция должна принимать много аргументов и применяется к элементам из всех итераций параллельно.
Если один итерабельность короче другого, предполагается, что он расширен с помощью элементов None.
Если функция None
, предполагается функция тождества; если есть несколько аргументов, map()
возвращает список, состоящий из кортежей, содержащих соответствующие элементы из всех итераций (своего рода операция транспонирования).
Итерируемыми аргументами могут быть последовательность или любой итерируемый объект; результат всегда является списком.
Какую роль это играет в создании декартова произведения?
content = map(tuple, array)
Какое влияние имеет место в кортеже в любом месте? Я также заметил, что без функции отображения выходной сигнал abc
и вместе с ним он a, b, c
.
Я хочу полностью понять эту функцию. Ссылочные определения также трудно понять. Слишком много причудливого пуха.
Ответы
Ответ 1
map
не является особенно питоническим. Вместо этого я бы рекомендовал использовать списки:
map(f, iterable)
в основном эквивалентно:
[f(x) for x in iterable]
map
сам по себе не может делать декартово произведение, потому что длина его выходного списка всегда совпадает с его входным списком. Вы можете тривиально сделать декартово произведение со списком, хотя:
[(a, b) for a in iterable_a for b in iterable_b]
Синтаксис немного запутанный, что в основном эквивалентно:
result = []
for a in iterable_a:
for b in iterable_b:
result.append((a, b))
Ответ 2
map
вообще не относится к декартовому произведению, хотя я представляю, что кто-то хорошо разбирающийся в функциональном программировании может придумать какое-то непонятное для понимания способ генерации одного с помощью map
.
map
в Python 3 эквивалентен этому:
def map(func, iterable):
for i in iterable:
yield func(i)
и единственная разница в Python 2 заключается в том, что он будет создавать полный список результатов, чтобы возвращать все сразу, а не yield
ing.
Хотя соглашение Python обычно предпочитает использование списков (или выражений генератора) для достижения того же результата, что и вызов map
, особенно если вы используете в качестве первого аргумента лямбда-выражение:
[func(i) for i in iterable]
В качестве примера того, что вы просили в комментариях к вопросу - "превратить строку в массив", "массивом" вы, вероятно, хотите либо кортеж, либо список (оба они ведут себя как массивы из другие языки) -
>>> a = "hello, world"
>>> list(a)
['h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd']
>>> tuple(a)
('h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd')
Использование map
здесь было бы, если вы начинаете со списком строк вместо одной строки - map
может их перечислить индивидуально:
>>> a = ["foo", "bar", "baz"]
>>> list(map(list, a))
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']]
Обратите внимание, что map(list, a)
эквивалентен в Python 2, но в Python 3 вам нужен вызов list
, если вы хотите сделать что-то другое, кроме как передать его в цикл for
(или функцию обработки, такую как sum
который требует только итерации, а не последовательности). Но также обратите внимание на то, что обычно рекомендуется понимание списка:
>>> [list(b) for b in a]
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']]
Ответ 3
map
создает новый список, применяя функцию к каждому элементу источника:
xs = [1, 2, 3]
# all of those are equivalent — the output is [2, 4, 6]
# 1. map
ys = map(lambda x: x * 2, xs)
# 2. list comprehension
ys = [x * 2 for x in xs]
# 3. explicit loop
ys = []
for x in xs:
ys.append(x * 2)
n-ary map
эквивалентен объединению итераций ввода и одновременному использованию функции преобразования для каждого элемента этого промежуточного списка. Это не декартово произведение:
xs = [1, 2, 3]
ys = [2, 4, 6]
def f(x, y):
return (x * 2, y // 2)
# output: [(2, 1), (4, 2), (6, 3)]
# 1. map
zs = map(f, xs, ys)
# 2. list comp
zs = [f(x, y) for x, y in zip(xs, ys)]
# 3. explicit loop
zs = []
for x, y in zip(xs, ys):
zs.append(f(x, y))
Я использовал zip
здесь, но поведение map
на самом деле немного отличается, когда итерали не имеют одинакового размера - как указано в его документации, он расширяет итерации, чтобы содержать None
.
Ответ 4
Упрощая немного, вы можете представить map()
что-то вроде этого:
def mymap(func, lst):
result = []
for e in lst:
result.append(func(e))
return result
Как вы можете видеть, он принимает функцию и список и возвращает новый список с результатом применения функции к каждому из элементов в списке ввода. Я сказал "упростить бит", потому что на самом деле map()
может обрабатывать более одного итерабельного:
Если передаются дополнительные повторяющиеся аргументы, функция должна принимать много аргументов и применяется к элементам из всех итераций параллельно. Если один итерабельность короче другого, предполагается, что он расширен с помощью элементов None.
Во второй части вопроса: Какую роль это играет в создании декартова произведения? ну, map()
можно было бы использовать для создания декартова произведения такого списка:
lst = [1, 2, 3, 4, 5]
from operator import add
reduce(add, map(lambda i: map(lambda j: (i, j), lst), lst))
... Но, честно говоря, использование product()
- гораздо более простой и естественный способ решить проблему:
from itertools import product
list(product(lst, lst))
В любом случае результатом является декартово произведение lst
, как определено выше:
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5),
(2, 1), (2, 2), (2, 3), (2, 4), (2, 5),
(3, 1), (3, 2), (3, 3), (3, 4), (3, 5),
(4, 1), (4, 2), (4, 3), (4, 4), (4, 5),
(5, 1), (5, 2), (5, 3), (5, 4), (5, 5)]
Ответ 5
Надеюсь, что это поможет кому-то новому в программировании и питоне:
Функция map()
должна применять одну и ту же процедуру к каждому item
в iterable data structure
, например, lists
, generators
, strings
и другие вещи.
Давайте посмотрим на пример:
map()
может iterate
по каждому item
в list
и применять function
к каждому item
, чем return
(возвращает вас) new list
.
Подумайте, что у вас есть function
, который принимает число (integer
), добавляет 1 к этому номеру и возвращает его.
def add_one(num):
new_num = num + 1
return num
У вас также есть list
чисел (integers
)
my_list = [1,3,6,7,8,10]
если вы хотите increment
каждое число (integer
) в list
, вы можете сделать следующее:
map(add_one, my_list)
Примечание: минимум map()
требуется два arguments
. Сначала a function
имя и второе что-то вроде list
.
результат вышеприведенного примера, map()
вернет вам это:
[2, 4, 7, 8, 9, 11]
Давайте посмотрим на некоторые другие интересные вещи, которые может сделать map()
.
map()
может принимать несколько iterables
(lists, strings, etc
) и передавать element
из каждого list
(я использую список в качестве примера) в function
как argument
.
У нас есть следующие списки:
list_one = [1, 2, 3, 4, 5]
list_two = [11, 12, 13, 14, 15]
list_three = [21, 22, 23, 24, 25]
map()
может сделать вас new list
, который содержит добавление элементов в конкретном index
(позиции).
Теперь помните map()
, требуется function
.
def add_from_three_lists(num1, num2, num3):
total_num = num1 + num2 + num3
return total_num
теперь позволяет использовать функцию map()
map(add_from_three_lists, list_one, List_two, list_three)
и вы получите:
[33, 36, 39, 42, 45]
ПОМНИТЕ:
В Python2 map()
будет iterate
(пройти через элементы lists
) в соответствии с самым длинным list
и передать NoneType
функции для более короткого lists
, поэтому ваш function
должен найдите NoneType
и обработайте их, иначе вы получите errors
. В python 3 map()
будет идти только по кратчайшему list
. Кроме того, в Python 3, map()
возвращает итератор, а не список.