了解地图功能

Web*_*ter 290 python map-function

map(function, iterable, ...)
Run Code Online (Sandbox Code Playgroud)

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

如果一个iterable比另一个短,则假定使用None项扩展.

如果是Nonefunction,则假定为identity函数; 如果有多个参数,则map()返回一个由包含所有迭代中相应项的元组组成的列表(一种转置操作).

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

这在制作笛卡尔积的过程中扮演什么角色?

content = map(tuple, array)
Run Code Online (Sandbox Code Playgroud)

将元组放在哪里有什么影响?我也注意到,如果没有map函数,输出就是abc和它一样a, b, c.

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

dav*_*ave 405

map不是特别pythonic.我建议使用列表推导代替:

map(f, iterable)
Run Code Online (Sandbox Code Playgroud)

基本上相当于:

[f(x) for x in iterable]
Run Code Online (Sandbox Code Playgroud)

map它本身不能做笛卡尔积,因为它的输出列表的长度总是与它的输入列表相同.您可以通过列表理解轻松地执行笛卡尔积:

[(a, b) for a in iterable_a for b in iterable_b]
Run Code Online (Sandbox Code Playgroud)

语法有点令人困惑 - 这基本上等同于:

result = []
for a in iterable_a:
    for b in iterable_b:
        result.append((a, b))
Run Code Online (Sandbox Code Playgroud)

  • 我发现使用`map`比列表推导更简洁,至少在你展示的情况下如此. (27认同)
  • map更快,因为它不会根据迭代器的长度调用函数.调用函数有开销..观看6:00 https://www.youtube.com/watch?v=SiXyyOA6RZg&t=813s (8认同)

lvc*_*lvc 80

map根本不涉及笛卡尔积,尽管我认为精通函数式编程的人可能想出一些不可能理解的生成一个使用的方法map.

map 在Python 3中相当于:

def map(func, iterable):
    for i in iterable:
        yield func(i)
Run Code Online (Sandbox Code Playgroud)

并且Python 2的唯一区别在于它将构建一个完整的结果列表,以便一次性返回而不是yielding.

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

[func(i) for i in iterable]
Run Code Online (Sandbox Code Playgroud)

作为你在问题的评论中所要求的一个例子 - "将一个字符串变成一个数组",通过'array'你可能想要一个元组或一个列表(它们都表现得像其他语言的数组) -

 >>> 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')
Run Code Online (Sandbox Code Playgroud)

map如果你从字符串列表开始而不是单个字符串,那么这里的用法就是:map可以单独地分解所有字符串:

>>> a = ["foo", "bar", "baz"]
>>> list(map(list, a))
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']]
Run Code Online (Sandbox Code Playgroud)

请注意,这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']]
Run Code Online (Sandbox Code Playgroud)


Cat*_*lus 34

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)
Run Code Online (Sandbox Code Playgroud)

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))
Run Code Online (Sandbox Code Playgroud)

我在zip这里使用过,map但当iterables的大小不同时,行为实际上略有不同 - 正如其文档中所述,它将iterables扩展为包含None.


Ósc*_*pez 20

简化一下,你可以想象map()做这样的事情:

def mymap(func, lst):
    result = []
    for e in lst:
        result.append(func(e))
    return result
Run Code Online (Sandbox Code Playgroud)

如您所见,它接受一个函数和一个列表,并返回一个新列表,其中包含将函数应用于输入列表中的每个元素的结果.我说"简化一点"因为实际上map()可以处理多个迭代:

如果传递了其他可迭代参数,则函数必须采用那么多参数,并且并行地应用于所有迭代的项.如果一个iterable比另一个短,则假定使用None项扩展.

对于问题的第二部分:这在制作笛卡尔积中起到了什么作用?好吧,map() 可以用于生成列表的笛卡尔积,如下所示:

lst = [1, 2, 3, 4, 5]

from operator import add
reduce(add, map(lambda i: map(lambda j: (i, j), lst), lst))
Run Code Online (Sandbox Code Playgroud)

...但说实话,使用product()是解决问题的一种更简单自然的方法:

from itertools import product
list(product(lst, lst))
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,结果都是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)]
Run Code Online (Sandbox Code Playgroud)


Blo*_*ooB 15

map()函数用于对可迭代数据结构中的每个项应用相同的过程,如列表,生成器,字符串和其他内容.

让我们看一个例子: map()可以迭代列表中的每个项目并将函数应用于每个项目,而不是返回(返回)新列表.

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

def add_one(num):
  new_num = num + 1
  return new_num
Run Code Online (Sandbox Code Playgroud)

您还有一个数字列表:

my_list = [1, 3, 6, 7, 8, 10]
Run Code Online (Sandbox Code Playgroud)

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

>>> map(add_one, my_list)
[2, 4, 7, 8, 9, 11]
Run Code Online (Sandbox Code Playgroud)

注意:至少map()需要两个参数.首先是一个函数名,第二个是列表.

让我们看看其他一些很酷的事情map(). map()可以采用多个迭代(列表,字符串等),并将每个iterable中的元素作为参数传递给函数.

我们有三个清单:

list_one = [1, 2, 3, 4, 5]
list_two = [11, 12, 13, 14, 15]
list_three = [21, 22, 23, 24, 25]
Run Code Online (Sandbox Code Playgroud)

map() 可以使您成为一个新列表,其中包含在特定索引处添加元素.

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

>>> map(sum, list_one, list_two, list_three)
[33, 36, 39, 42, 45]
Run Code Online (Sandbox Code Playgroud)

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


Ran*_*nga 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
Run Code Online (Sandbox Code Playgroud)

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