问题:了解地图功能
map(function, iterable, ...)
将函数应用于每个iterable项目,并返回结果列表。如果传递了其他可迭代参数,则函数必须采用那么多参数,并且并行地将其应用于所有可迭代对象的项。
如果一个可迭代项短于另一个可迭代项,则假定它扩展为None。
如果function是None
,则假定身份函数;如果有多个参数,则map()
返回一个由元组组成的列表,其中包含所有可迭代对象中的对应项(一种转置操作)。
可迭代参数可以是序列或任何可迭代对象。结果总是一个列表。
这在制作笛卡尔积时起什么作用?
content = map(tuple, array)
将元组放在任何地方会有什么作用?我也注意到,如果没有地图功能的输出abc
,并与它,它的a, b, c
。
我想完全了解此功能。参考定义也很难理解。花哨的绒毛太多。
map(function, iterable, ...)
Apply function to every item of iterable and return a list of the results. If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel.
If one iterable is shorter than another it is assumed to be extended with None items.
If function is None
, the identity function is assumed; if there are multiple arguments, map()
returns a list consisting of tuples containing the corresponding items from all iterables (a kind of transpose operation).
The iterable arguments may be a sequence or any iterable object; the result is always a list.
What role does this play in making a Cartesian product?
content = map(tuple, array)
What effect does putting a tuple anywhere in there have? I also noticed that without the map function the output is abc
and with it, it’s a, b, c
.
I want to fully understand this function. The reference definitions is also hard to understand. Too much fancy fluff.
回答 0
map
不是特别的pythonic。我建议改用列表推导:
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))
map
isn’t particularly pythonic. I would recommend using list comprehensions instead:
map(f, iterable)
is basically equivalent to:
[f(x) for x in iterable]
map
on its own can’t do a Cartesian product, because the length of its output list is always the same as its input list. You can trivially do a Cartesian product with a list comprehension though:
[(a, b) for a in iterable_a for b in iterable_b]
The syntax is a little confusing — that’s basically equivalent to:
result = []
for a in iterable_a:
for b in iterable_b:
result.append((a, b))
回答 1
map
尽管我想象一个精通函数式编程的人可能会提出一些无法理解的使用生成方法的方法,但它与笛卡尔积完全无关map
。
map
Python 3中的等效于此:
def map(func, iterable):
for i in iterable:
yield func(i)
Python 2的唯一区别是它将建立完整的结果列表以立即返回所有结果而不是yield
ing。
尽管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
doesn’t relate to a Cartesian product at all, although I imagine someone well versed in functional programming could come up with some impossible to understand way of generating a one using map
.
map
in Python 3 is equivalent to this:
def map(func, iterable):
for i in iterable:
yield func(i)
and the only difference in Python 2 is that it will build up a full list of results to return all at once instead of yield
ing.
Although Python convention usually prefers list comprehensions (or generator expressions) to achieve the same result as a call to map
, particularly if you’re using a lambda expression as the first argument:
[func(i) for i in iterable]
As an example of what you asked for in the comments on the question – “turn a string into an array”, by ‘array’ you probably want either a tuple or a list (both of them behave a little like arrays from other languages) –
>>> 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')
A use of map
here would be if you start with a list of strings instead of a single string – map
can listify all of them individually:
>>> a = ["foo", "bar", "baz"]
>>> list(map(list, a))
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']]
Note that map(list, a)
is equivalent in Python 2, but in Python 3 you need the list
call if you want to do anything other than feed it into a for
loop (or a processing function such as sum
that only needs an iterable, and not a sequence). But also note again that a list comprehension is usually preferred:
>>> [list(b) for b in a]
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']]
回答 2
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
当可迭代项的大小不同时,行为实际上稍有不同–如其文档中所述,它将可迭代项扩展为contains None
。
map
creates a new list by applying a function to every element of the source:
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
is equivalent to zipping input iterables together and then applying the transformation function on every element of that intermediate zipped list. It’s not a Cartesian product:
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))
I’ve used zip
here, but map
behaviour actually differs slightly when iterables aren’t the same size — as noted in its documentation, it extends iterables to contain None
.
回答 3
简化一下,您可以想象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)]
Simplifying a bit, you can imagine map()
doing something like this:
def mymap(func, lst):
result = []
for e in lst:
result.append(func(e))
return result
As you can see, it takes a function and a list, and returns a new list with the result of applying the function to each of the elements in the input list. I said “simplifying a bit” because in reality map()
can process more than one iterable:
If additional iterable arguments are passed, function must take that many arguments and is applied to the items from all iterables in parallel. If one iterable is shorter than another it is assumed to be extended with None items.
For the second part in the question: What role does this play in making a Cartesian product? well, map()
could be used for generating the cartesian product of a list like this:
lst = [1, 2, 3, 4, 5]
from operator import add
reduce(add, map(lambda i: map(lambda j: (i, j), lst), lst))
… But to tell the truth, using product()
is a much simpler and natural way to solve the problem:
from itertools import product
list(product(lst, lst))
Either way, the result is the cartesian product of lst
as defined above:
[(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)]
回答 4
该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()
返回迭代器,而不是列表。
The map()
function is there to apply the same procedure to every item in an iterable data structure, like lists, generators, strings, and other stuff.
Let’s look at an example:
map()
can iterate over every item in a list and apply a function to each item, than it will return (give you back) the new list.
Imagine you have a function that takes a number, adds 1 to that number and returns it:
def add_one(num):
new_num = num + 1
return new_num
You also have a list of numbers:
my_list = [1, 3, 6, 7, 8, 10]
if you want to increment every number in the list, you can do the following:
>>> map(add_one, my_list)
[2, 4, 7, 8, 9, 11]
Note: At minimum map()
needs two arguments. First a function name and second something like a list.
Let’s see some other cool things map()
can do.
map()
can take multiple iterables (lists, strings, etc.) and pass an element from each iterable to a function as an argument.
We have three lists:
list_one = [1, 2, 3, 4, 5]
list_two = [11, 12, 13, 14, 15]
list_three = [21, 22, 23, 24, 25]
map()
can make you a new list that holds the addition of elements at a specific index.
Now remember map()
, needs a function. This time we’ll use the builtin sum()
function. Running map()
gives the following result:
>>> map(sum, list_one, list_two, list_three)
[33, 36, 39, 42, 45]
REMEMBER:
In Python 2 map()
, will iterate (go through the elements of the lists) according to the longest list, and pass None
to the function for the shorter lists, so your function should look for None
and handle them, otherwise you will get errors. In Python 3 map()
will stop after finishing with the shortest list. Also, in Python 3, map()
returns an iterator, not a list.
回答 5
Python3-映射(函数,可迭代)
没有完全提及的一件事(尽管@BlooB kinda提到了)是地图返回地图对象而不是列表。在初始化和迭代的时间性能方面,这是一个很大的差异。考虑这两个测试。
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对象进行迭代比仅简单地迭代可迭代对象要花费更长的时间。这意味着传递给map()的函数不会应用到每个元素,直到在迭代中到达该元素为止。如果要使用列表,请使用列表理解。如果您打算在for循环中进行迭代并且会在某个时候中断,请使用map。
Python3 – map(func, iterable)
One thing that wasn’t mentioned completely (although @BlooB kinda mentioned it) is that map returns a map object NOT a list. This is a big difference when it comes to time performance on initialization and iteration. Consider these two tests.
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
As you can see initializing the map function takes almost no time at all. However iterating through the map object takes longer than simply iterating through the iterable. This means that the function passed to map() is not applied to each element until the element is reached in the iteration. If you want a list use list comprehension. If you plan to iterate through in a for loop and will break at some point, then use map.