Python: 使用map函数独立处理每一行
假设有这样一个列表:
[[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 个回答
我建议你先看看这个帖子。那里的最佳回答提供了一些很有用的信息。
我还会看看[这个]关于lambda函数的页面,因为每当我使用map的时候,通常也会用到lambda...
至于你发的例子...
我觉得不应该用mapping来处理这个。我更倾向于在这里使用列表推导式。
v=[[sum(i[0:2]),0,sum(i[2:]),0] for i in m]
如果子数组的长度固定为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)
这不是最简单的解决方案,但它展示了如何在列表的列表上使用 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
这要看你的函数到底是什么。
首先:如果这个函数,比如说 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]
>>>
要理解这段代码:
[sum(row)]
表示一个只有一个元素的列表,这个元素是行的总和 ——[14]
。[0,] * (len(row) - 1)
会生成一个长度比行中元素少一个的零列表,查看下面的代码示例:>>> row = [2, 4, 0, 8] # 4 elements >>> [0,] * (len(row) -1 ) [0, 0, 0] # 3 zeros >>>
这个 * 运算符同样可以应用于元组和字符串。
所以从上面,我生成了两个独立的列表,最后把它们用 + 连接起来,如下:
>>> row = [2, 4, 0, 8] >>> [sum(row)] + [0,] * (len(row) -1 ) [14, 0, 0, 0] # that is what you wants
现在,你想对每一行 i
∈ m
执行 [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]