使用列表列表中特定索引处的值进行操作

Operation with values at specific indexes in a list of list

我目前正在 python (2.x) 中编写一个小脚本,并且有一部分代码我想改进但不知道如何做。

我有 listlist,如下所示:

my_list = [["abc",1,2,"def"],["ghi",4,5,"klm"],["nop",6,7,"qrs"]]

我需要获取索引 1 处所有整数的总和以及索引 2 处所有整数的总和。为此,我目前有:

sum1, sum2 = 0, 0
for i in my_list:
  sum1 += i[1]
  sum2 += i[2]

有什么更 pythonic 的方法可以做到这一点?也许使用 reducelambda 函数之类的?

一个更 pythonic 的方法是使用 sum 函数和 for ... in ... 生成器,并在一行中完成所有工作,如下所示:

sum1, sum2 = sum(x[1] for x in my_list), sum(x[2] for x in my_list)

最 Pythonic 的可能是列表理解:

my_list = [["abc",1,2,"def"],["ghi",4,5,"klm"],["nop",6,7,"qrs"]]

总结:

sum1 = sum(l[1] for l in my_list)
sum2 = sum(l[2] for l in my_list)

哪个returns:

sum1 = 11
sum2 = 14

如果您不介意循环两次,您可以 sum(x[1] for x in in my_list), sum(x[2] for x in my_list)

reduce(lambda acc, l: (acc[0] + l[1], acc[1] + l[2]), my_list, (0, 0)) 如果您想同时进行这两项操作。这将 return 一个元组,第一个元素的总和为 [1],第二个元素的总和为 [2]

您可以使用 zip 和列表理解

>>> lst = [["abc",1,2,"def"],["ghi",4,5,"klm"],["nop",6,7,"qrs"]]
>>> [sum(i) for i in list(zip(*lst))[1:3]]
[11, 14]

或使用 zipislice class 来自 itertools

>>> from itertools import islice
>>> [sum(i) for i in islice(zip(*lst), 1, 3)]
[11, 14]

这是一个不使用生成器表达式的单行代码。使用 zip 加上解包来转置列表,然后使用 map.

在所有数字列上 运行 sum
>>> map(sum, zip(*my_list)[1:-1])
[11, 14]

不幸的是,它在 3.X 中有点冗长,因为您无法对 zip 对象进行切片。

a,b = map(sum, list(zip(*my_list))[1:-1])

您可以使用 reduce,但是,由于序列中的元素是列表,因此您需要将初始值设置为 0。例如:

reduce(lambda total, list: total+list[1], my_list, 0)  # integers at index 1
reduce(lambda total, list: total+list[2], my_list, 0)  # integers at index 2