功能

  • map()函数用于对容器中的元素进行映射(或变换)。例如:我 想将列表中的所有元素都乘以2,返回新的列表。

如何迭代Map容器 map 迭代器_匿名函数

为什么map要设计成一个迭代器的样子呢?

  • 节约内存:不再在内存中一次性的生成一个结果列表

语法

map(function,iterable,...)

参数:

  • function:是一个提供变换规则的函数,返回变换之后的元素。
  • iterator:要映射的可迭代对象,可以是多个序列

可以向 map 函数传递多个 iterable,对应的函数也要接受相同序列数量的参数,如果 iterable 的数量不一样,则取短板,其余的放弃。function 可以使用匿名函数 lambda。

如何迭代Map容器 map 迭代器_如何迭代Map容器_02

返回值:

  • 在python2中返回可迭代对象(列表)
  • 在python3中返回可迭代结果(迭代器),如果需要的话,可以用list(…)来强制一个列表

注意:

  • 它是一次性的,在遍历过结果一次之后,就用尽了

原理

  • 在调用map时,iterable会被遍历,它的元素被逐一传入function()函数中,在function()函数中对元素进行变换

实例

单个可迭代对象

# 单个对象
def add_1(x):
    return x + 1

m = map(add_1, [1,2,3,4])
list(m)
# [2, 3, 4, 5]

多个可迭代对象

# 多个对象
def add_num(x, y):
    return x + y

m = map(add_num, [1,2,3,4], [1,2,3,4])
list(m)
# [2, 4, 6, 8]

多个序列如果长度不一样,只会处理到最短的元素位置:

# 对象不同长度
def add_num(x, y):
    return x + y

m = map(add_num, [1,2,3,4], [1, 2])
list(m)
# [2, 4]

有几个序列,函数就要承接几个参数:

def add_num(x, y, z):
    return x + y + z

l1 = [1, 2, 3]
[*map(add_num, l1, l1, l1)]
[3, 6, 9]

使用匿名函数

# 匿名函数
m = map(lambda x,y: x+y, [1,2,3,4], [1, 2])
list(m)
# [2, 4]

其他

对于函数的输入已经是参数元组的情况,可以 使用 itertools.starmap() 操作。它创建一个迭代器,使用从可迭代对象中获取的参数来计算该函数。当参数对应的形参已从一个单独可迭代对象组合为元组时(数据已被“预组对”)可用此函数代替 map()。map() 与 starmap() 之间的区别可以类比 function(a,b) 与 function(*c) 的区别。

import itertools

t = [(2,5), (3,4)]
# 元组内操作(相乘)
sm = itertools.starmap(lambda x,y: x*y, t)
list(sm)
# [10, 12]

列表表达式

map 的功能可以用列表表达式来代替:

l = [-2, -1, 0]
[abs(x) for x in l]
# [2, 1, 0]

[x**2 for x in l]
# [4, 1, 0]

l_1 = [1, 2, 3]
l_2 = [10, 20, 30]
[x * y for x, y in zip(l_1, l_2)]
# [10, 40, 90]

在大多数情况下,与 map 相比,使用列表生成器式更简洁明了,但也有人认为 map 作为高阶函数,能更加突出函数,弱化了循环的表达,让处理逻辑看起来更加明显。

NumPy 代替

在数据科学中,不需要按 map 模式的计算,两个序列之间的操作被认为是一个矩阵计算,NumPy 可以非常好地完成这些,比 map() 和列表表示更为明确。

import numpy as np

a = np.array([-2, -1, 0])
print(np.abs(a))
# [2 1 0]

print(a**2)
# [4 1 0]

a_1 = np.array([1, 2, 3])
a_2 = np.array([10, 20, 30])
print(a_1 * a_2)
# [10 40 90]