Понимание функции карты

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() возвращает итератор, а не список.