map(function, iterable, ...)


将函数应用于可迭代的每个项目并返回结果列表。如果传递了其他可迭代的参数,则函数必须采用那么多参数,并且并行地将其应用于所有可迭代的项目。

如果一个可迭代项短于另一个可迭代项,则假定它扩展了None项目。

如果函数为None,则假定身份函数;如果有多个参数,则map()返回一个包含元组的列表,该元组包含所有可迭代对象的对应项(一种转置操作)。

可迭代参数可以是序列或任何可迭代对象;结果始终是一个列表。

这在制造笛卡尔积时起什么作用?

content = map(tuple, array)


将元组放在任何地方有什么作用在那儿有?我还注意到,没有map函数,输出为abc,而输出为a, b, c

我想完全理解此功能。参考定义也很难理解。花哨的绒毛太多。

评论

您实际上想要实现什么?为什么要专门使用地图?

@WebMaster是的,根据您粘贴的文档中的第一句话-“将函数应用于可迭代的每个项目”。本段的其余部分是关于更复杂的情况的,例如map(None,a,b,c)可以执行zip(a,b,c)。但是实际上,您很少看到这种情况,这恰恰是因为zip调用是等效的。

我正在努力学习python,并且每当我在python.org中打开一个定义时。第一句话之后,我什么都不懂。好的。谢谢。

元组是一个函数(很好,它的细微之处在于它,但它的行为像一个函数),它需要一个可迭代的函数,并为您提供具有相同元素的元组-因此tuple([1、2、3])等效于( 1,2,3)。对于map(tuple,array),array将是一个可迭代的迭代器(考虑一个列表列表),它使您将每个内部列表都变成一个元组。

通常,最重要的是所有功能文档的第一句话。如果您了解这一点,便可以理解。它的其余部分详细说明了该行为,而其中的某些行为从一开始就有点不透明,您可能需要在此基础上遇到一个奇怪的习惯用法,然后才能看到“哦,那是什么意思!”。但是一旦掌握了一些内置功能,您就应该能够更加轻松地理解文档了。

#1 楼

map不是特别Pythonic。我建议改用列表推导:

map(f, iterable)



[f(x) for x in iterable]


map own不能执行笛卡尔乘积,因为其输出列表的长度始终与输入列表相同。您可以通过列表理解来简单地做笛卡尔积:

[(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))


评论


我发现使用map的详细程度要比列表理解的详细程度小得多,至少在您所演示的情况下如此。

– marbel
16 Dec 14 '16:40



如何将地图用于属性? [[in.object,str)中v的[v .__ name__]的映射等效于什么?

– A Sz
17年7月19日在10:53

@ASz地图(lambda v:v .__ name__,列表)怎么样?

–基连
17-10-13在7:55

map更快,因为它不会根据迭代器的长度来调用函数。调用函数会产生开销。观看6:00 youtube.com/watch?v=SiXyyOA6RZg&t=813s

– anati
17年11月22日在10:47

@anati我以为map有时比理解要快,有时不是,只是因为函数调用开销?尤其是,我学到的启发式方法是,在使用map时,您需要引入一个额外的函数调用,理解速度会更快吗?例如。我被认为是map(lambda foo:foo.bar,my_list)比my_list中的foo的foo.bar慢,甚至map(operator.add,my_list_of_pairs)的x,y都比x + y慢。 my_list_of_pairs,正是由于附加的函数调用。

–mtraceur
18-2-20在22:21



#2 楼

map根本与笛卡尔积无关,尽管我认为精通函数式编程的人可能会提出一些无法理解的使用map生成笛卡尔积的方法。

Python 3中的map等效于此:

def map(func, iterable):
    for i in iterable:
        yield func(i)


,Python 2的唯一区别是它将建立完整列表的结果可立即返回全部而不是yield

尽管Python约定通常更喜欢列表推导(或生成器表达式)来实现与调用map相同的结果,尤其是如果您使用的是lambda表达式作为第一个参数:

[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']]


评论


map(fun x->(x,x))似乎很难理解...(尽管从地图中获取真正的笛卡尔积是不可能的,但是地图产生的任何东西总是列表的某种形式)

–克里斯托弗·米辛斯基(Kristopher Micinski)
2012年6月11日在2:04



#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元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

评论


复杂,试图消化这篇文章

–网站管理员
2012年6月11日下午2:25

@WebMaster它有什么复杂之处?

– Jossie Calderon
16年7月12日在16:09



我认为最好的答案。在示例中将lambda用作函数可以很清楚地看出。

– Sheldonzy
18年2月24日在11:49

不幸的是,所有这些都不相等-列表理解和显式循环的输出为[2,4,6],但是地图返回了地图对象-例如,我得到了这个:然后我必须强制进入列表。

–́leerssej
19/12/3在6:18

#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()函数可以将相同的过程应用于可迭代数据结构中的每个项目,例如列表,生成器,字符串和其他内容。

让我们看一个示例:
map()可以遍历列表中的每个项目,并对每个项目应用一个函数,它会返回(给您)新列表。

想象一下您有一个带数字的函数,将数字加1数字并返回它:

def add_one(num):
  new_num = num + 1
  return new_num


如果您需要,还可以有一个数字列表:

my_list = [1, 3, 6, 7, 8, 10]


要递增列表中的每个数字,可以执行以下操作:

>>> map(add_one, my_list)
[2, 4, 7, 8, 9, 11]


注意:map()至少需要两个参数。首先是一个函数名,其次是一个列表。

让我们看看map()可以完成的其他一些很酷的事情。
map()可以接受多个可迭代项(列表,字符串等)并传递一个元素从每个可迭代对象到函数作为参数。

我们有三个列表:

list_one = [1, 2, 3, 4, 5]
list_two = [11, 12, 13, 14, 15]
list_three = [21, 22, 23, 24, 25]


map()可以使您拥有一个包含以下内容的新列表:

现在记住map(),需要一个功能。这次,我们将使用内置的sum()函数。运行map()会得到以下结果:

>>> map(sum, list_one, list_two, list_three)
[33, 36, 39, 42, 45]


记住:
在Python 2 map()中,将根据最长的时间进行迭代(遍历列表中的元素)列表,然后将None传递给较短列表的函数,因此您的函数应查找None并进行处理,否则会出错。在Python 3中,map()将在完成最短列表后停止。另外,在Python 3中,map()返回一个迭代器,而不是列表。

#6 楼

Python3-map(func,可迭代)
没有完全提到的一件事(尽管@BlooB kinda提到了)是map返回一个地图对象而不是一个列表。在初始化和迭代的时间性能方面,这是一个很大的差异。考虑这两个测试。
import time
def test1(iterable):
    a = time.clock()
    map(str, iterable)
    a = time.clock() - a

    b = time.clock()
    [ str(x) for x in iterable ]
    b = time.clock() - b

    print(a,b)


def test2(iterable):
    a = time.clock()
    [ x for x in map(str, iterable)]
    a = time.clock() - a

    b = time.clock()
    [ str(x) for x in iterable ]
    b = time.clock() - b

    print(a,b)


test1(range(2000000))  # Prints ~1.7e-5s   ~8s
test2(range(2000000))  # Prints ~9s        ~8s

您可以看到初始化map函数几乎不需要时间。但是,遍历map对象所花费的时间要比简单地遍历iterable所花费的时间更长。这意味着传递给map()的函数不会应用到每个元素,直到在迭代中到达该元素为止。如果要使用列表,请使用列表理解。如果您打算在for循环中进行迭代并且会在某个时候中断,请使用map。