Python: 使用map函数独立处理每一行

3 投票
4 回答
4545 浏览
提问于 2025-04-18 03:28

假设有这样一个列表:

[[2,4,0,8],[0,2,4,8],[8,0,2,4],[8,2,0,4]]

大家好,我想知道怎么用map函数来处理列表中每一行的元素?

比如说,如果我想把每个列表中的数对相加:

[[6,0,8,0],[2,0,12,0],[8,0,6,0],[10,0,4,0]]

其实我对map函数不是很了解,也没找到什么有用的文章来讲解映射。希望能给我一些链接。谢谢!!!

4 个回答

0

我建议你先看看这个帖子。那里的最佳回答提供了一些很有用的信息。

我还会看看[这个]关于lambda函数的页面,因为每当我使用map的时候,通常也会用到lambda...

至于你发的例子...

我觉得不应该用mapping来处理这个。我更倾向于在这里使用列表推导式。

v=[[sum(i[0:2]),0,sum(i[2:]),0] for i in m]
1

如果子数组的长度固定为4个元素,那么对于输入数组中的每个元素 [a, b, c, d],你想输出一个新的元素 [a+b, 0, c+d, 0]

你可以使用 map 来实现这个功能,具体方法如下:

map(lambda x: [x[0]+x[1], 0, x[2]+x[3], 0], input_array)
1

这不是最简单的解决方案,但它展示了如何在列表的列表上使用 map

无论你想怎么定义 addPairs 方法,它都必须接收一个 list 作为输入,并返回一个 list

lst = [[2,4,0,8],[0,2,4,8],[8,0,2,4],[8,2,0,4]]

def addPairs(y):
   out = []
   for i in xrange(len(y)):
      if i % 2 == 0:
        out.append(y[i] + y[i+1])
      else: out.append(0)
   return out


output = map(addPairs, lst)
print output
3

这要看你的函数到底是什么。

首先:如果这个函数,比如说 f,接受的是“完整行的列表”,那么你可以这样使用:

m = [[6, 0, 8, 0], [2, 0, 12, 0], [8, 0, 6, 0], [10, 0, 4, 0]]
map(f, m)

其次:如果函数 f 是接受每一个元素,那么你需要使用嵌套的 map(),像下面这样:

map(lambda r: map(f, r), m)

为了这个,你也可以使用列表推导式:

[map(f, r) for r in m] # I prefer this 

还有其他一些技巧,比如你可以使用 functools.partial。看看这个 例子

from functools import partial
newf = partial(map, f)
map(newf, m)

编辑:作为对评论的回应:

其实我主要想知道如何处理行中的元素。这意味着我也可以把所有元素加起来,比如 [2, 4, 0, 8],变成 [14, 0, 0, 0]

首先,我有点疑惑,为什么你想把列表 [2, 4, 0, 8] 转换成 [14, 0, 0, 0],为什么不直接输出 14 —— 也就是总和,看看你是否可以改进你的算法或程序设计。

无论如何,在Python中我们有一个 sum() 函数,查看文档 sum(iterable[, start]),例子(查看评论):

>>> row =  [2,4,0,8] 
>>> sum(row)  # just outputs sum of all elements, in rows
14

所以如果你想传递“一个列表的列表”,就像你在问题中提到的 m,那么你可以使用 map(sum, m),见下文:

>>> m = [[6, 0, 8, 0], [2, 0, 12, 0], [8, 0, 6, 0], [10, 0, 4, 0]]
>>> map(sum, m)  # call sum for each row (a list) in `m`
[14, 14, 14, 14] # sum of all individual list's elements 

但是如果你想像你问的那样生成一个列表,那么你可以使用 +(列表连接)运算符和总和,像这样:

>>> row =  [2, 4, 0, 8] 
>>> [sum(row)] + [0,] * (len(row) -1 )
[14, 0, 0, 0]
>>> 

要理解这段代码:

  1. [sum(row)] 表示一个只有一个元素的列表,这个元素是行的总和 —— [14]
  2. [0,] * (len(row) - 1) 会生成一个长度比行中元素少一个的零列表,查看下面的代码示例:

     >>> row =  [2, 4, 0, 8]   # 4 elements 
     >>> [0,] * (len(row) -1 )
     [0, 0, 0] # 3 zeros
     >>> 
    

    这个 * 运算符同样可以应用于元组和字符串。

  3. 所以从上面,我生成了两个独立的列表,最后把它们用 + 连接起来,如下:

    >>> row =  [2, 4, 0, 8] 
    >>> [sum(row)] + [0,] * (len(row) -1 )
    [14, 0, 0, 0]  # that is what you wants 
    

现在,你想对每一行 im 执行 [sum(row)] + [0,] * (len(row) - 1) 这个表达式,那么你可以使用带有 map() 的 lambda 表达式,如下:

>>> map(lambda row: [sum(row)] + [0,] * (len(row) -1 ), m)
[[14, 0, 0, 0], [14, 0, 0, 0], [14, 0, 0, 0], [14, 0, 0, 0]]

最好给 lambda 表达式起个名字:

>>> f = lambda r: [sum(r)] + [0,] * (len(r) -1 )
>>> f(row)
[14, 0, 0, 0]

然后使用 map()

>>> map(f, m)
[[14, 0, 0, 0], [14, 0, 0, 0], [14, 0, 0, 0], [14, 0, 0, 0]]

就像我在前面几行中建议的那样。再次强调,你也可以在这里使用列表推导式来代替调用 map(),像这样:

>>> [f(r) for r in m]

撰写回答