map(function, iterable, ...)
将函数应用于可迭代的每个项目并返回结果列表。如果传递了其他可迭代的参数,则函数必须采用那么多参数,并且并行地将其应用于所有可迭代的项目。
如果一个可迭代项短于另一个可迭代项,则假定它扩展了None项目。
如果函数为
None
,则假定身份函数;如果有多个参数,则map()
返回一个包含元组的列表,该元组包含所有可迭代对象的对应项(一种转置操作)。 可迭代参数可以是序列或任何可迭代对象;结果始终是一个列表。
这在制造笛卡尔积时起什么作用?
content = map(tuple, array)
将元组放在任何地方有什么作用在那儿有?我还注意到,没有map函数,输出为
abc
,而输出为a, b, c
。我想完全理解此功能。参考定义也很难理解。花哨的绒毛太多。
#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],但是地图返回了地图对象-例如,我得到了这个:
#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。
评论
您实际上想要实现什么?为什么要专门使用地图?@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将是一个可迭代的迭代器(考虑一个列表列表),它使您将每个内部列表都变成一个元组。
通常,最重要的是所有功能文档的第一句话。如果您了解这一点,便可以理解。它的其余部分详细说明了该行为,而其中的某些行为从一开始就有点不透明,您可能需要在此基础上遇到一个奇怪的习惯用法,然后才能看到“哦,那是什么意思!”。但是一旦掌握了一些内置功能,您就应该能够更加轻松地理解文档了。