Основное использование карты, itertools.imap и future_builtins.map

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

names = ['Fred', 'Wilma', 'Barney']

 

map(len, names) # map в Python 3.x является классом; его экземпляры повторяемы # Out:

В Python 3 - совместимая map включена в future_builtins модуль:

из карты импорта future_builtins # содержит карту map (), совместимую с Python 3.x (len, names) # см. ниже # Out:

map(len, names) 
# map() возвращает объект map

list(map(len, names)) # Out: [4, 5, 6] 

map() может быть заменена эквивалентным выражением генератора:

(len(item) for item in names)
# Out: <generator object <genexpr> at 0x00000195888D5FC0>

Отображение каждого значения в итерируемое

Например, вы можете взять абсолютное значение каждого элемента:

list(map(abs, (1, -1, 2, -2, 3, -3))) # the call to `list` is unnecessary in 2.x
# Out: [1, 1, 2, 2, 3, 3]

 

Анонимная функция также поддерживает отображение списка:

list(map(lambda x:x*2, [1, 2, 3, 4, 5]))
# Out: [2, 4, 6, 8, 10]

 

или преобразование десятичных значений в проценты:

def to_percent(num):
    return num * 100

list(map(to_percent, [0.95, 0.75, 1.01, 0.1]))
# Out: [95.0, 75.0, 101.0, 10.0]

 

или конвертировать доллары в евро (с учетом обменного курса):

from functools import partial
from operator import mul

rate = 0.9  # fictitious exchange rate, 1 dollar = 0.9 euros
dollars = {'under_my_bed': 1000,
           'jeans': 45,
           'bank': 5000}

sum(map(partial(mul, rate), dollars.values()))
# Out: 5440.5

 

functools.partial это удобный способ исправить параметры функций, так что они могут быть использованы с map вместо использования lambda или создания пользовательских функций.

Отображение значений разных итераций

Так , например вычисление среднего значения каждого i -й элемента множество итерируемых:

def average(*args):
    return float(sum(args)) / len(args)  # cast to float - only mandatory for python 2.x

measurement1 = [100, 111, 99, 97]
measurement2 = [102, 117, 91, 102]
measurement3 = [104, 102, 95, 101]

list(map(average, measurement1, measurement2, measurement3))
# Out: [102.0, 110.0, 95.0, 100.0]

Существуют различные требования , если более чем один итератор передается map в зависимости от версии питона:

Функция должна принимать столько параметров, сколько существует итераций:

def median_of_three(a, b, c):
    return sorted((a, b, c))[1]

list(map(median_of_three, measurement1, measurement2))
 

Ошибка типа: median_of_three () отсутствует 1 обязательный позиционный аргумент: 'c'

list(map(median_of_three, measurement1, measurement2, measurement3, measurement3))
 

Ошибка типа: median_of_three() принимает 3 позиционных аргумента, но 4 были заданы  `map`: отображение повторяется до тех пор, пока одна итерация еще не используется полностью, но предполагает, что из полностью использованных итераций используется 'None':

import operator

measurement1 = [100, 111, 99, 97]
measurement2 = [102, 117]

# Рассчитайте разницу между элементами
list(map(operator.sub, measurement1, measurement2))
# Out: [-2, -6]
list(map(operator.sub, measurement2, measurement1))
# Out: [2, 6]

Транспонирование с помощью Map: использование «None» в качестве аргумента функции (только для Python 2.x)

from itertools import imap
from future_builtins import map as fmap # Different name to highlight differences

image = [[1, 2, 3],
         [4, 5, 6],
         [7, 8, 9]]

list(map(None, *image)) # Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
list(fmap(None, *image)) # Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
list(imap(None, *image)) # Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]

image2 = [[1, 2, 3],
          [4, 5],
          [7, 8, 9]]
          
list(map(None, *image2)) # Out: [(1, 4, 7), (2, 5, 8), (3, None, 9)]  

# Fill missing values with None

list(fmap(None, *image2)) # Out: [(1, 4, 7), (2, 5, 8)]                

# ignore columns with missing values
list(imap(None, *image2))
# Out: [(1, 4, 7), (2, 5, 8)]                # dito

Серийное и параллельное картирование

Функция map() является встроенной функцией, что означает, что она доступна везде без необходимости использования оператора 'import'. Он доступен везде, как и print(). Например чтобы использовать функцию pretty print, то необходимо вначале использовать инструкцию import pprint, прежде чем я смог ее использовать. Таким образом, pprint не является встроенной функцией

Серийное картирование

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

Пример 1

insects = ['fly', 'ant', 'beetle', 'cankerworm']
f = lambda x: x + ' is an insect'
print(list(map(f, insects))) # the function defined by f is executed on each item of the iterable insects

Результат

['fly is an insect', 'ant is an insect', 'beetle is an insect', 'cankerworm is an insect']

 

Пример 2

print(list(map(len, insects))) # the len function is executed each item in the insect list

Результат

 [3, 3, 6, 10]

Параллельное отображение

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

 carnivores = ['lion', 'tiger', 'leopard', 'arctic fox']
herbivores = ['african buffalo', 'moose', 'okapi', 'parakeet']
omnivores = ['chicken', 'dove', 'mouse', 'pig']

def animals(w, x, y, z):
    return '{0}, {1}, {2}, and {3} ARE ALL ANIMALS'.format(w.title(), x, y, z)

 

Пример 3

 # Too many arguments
# observe here that map is trying to pass one item each from each of the four iterables to len. This leads len to complain that
# it is being fed too many arguments
print(list(map(len, insects, carnivores, herbivores, omnivores)))

 

результаты в

 TypeError: len() takes exactly one argument (4 given)

 

Пример 4

 # Too few arguments
# observe here that map is suppose to execute animal on individual elements of insects one-by-one. But animals complain when
# it only gets one argument, whereas it was expecting four.
print(list(map(animals, insects)))

 

результаты в

 TypeError: animals() missing 3 required positional arguments: 'x', 'y', and 'z'

 

Пример 5

 # here map supplies w, x, y, z with one value from across the list
import pprint
pprint.pprint(list(map(animals, insects, carnivores, herbivores, omnivores)))

 

результаты в

 ['Fly, lion, african buffalo, and chicken ARE ALL ANIMALS',
 'Ant, tiger, moose, and dove ARE ALL ANIMALS',
 'Beetle, leopard, okapi, and mouse ARE ALL ANIMALS',
 'Cankerworm, arctic fox, parakeet, and pig ARE ALL ANIMALS']

Синтаксис

Параметры

Примечания