是否可以对列表中的多个字段进行求和和解包?

时间:2017-08-04 02:13:53

标签: python

我的代码在某些领域变得非常冗长,如果有更多的Pythonic方法来完成以下任务,那就太好了:

total1 = 0
total2 = 0
total3 = 0
for x in list:
    total1 += x.field1
    total2 += x.field2
    total3 += x.field3

我还是Python的新手,但是我知道一些技巧,比如我可以用一半的方式剪掉一行......

total1 = sum(x.field1 for x in list)
total2 = sum(x.field2 for x in list);
total3 = sum(x.field3 for x in list);

但我不想为了节省SLOC而反复重复我的列表而牺牲性能。我想做的就是这样......

total1, total2, total3 = sum(x.field1, x.field2, x.field3 for x in list)

我已经尝试了几个版本,但我一直遇到语法错误。有没有办法在Python中做到这一点?

3 个答案:

答案 0 :(得分:1)

IIUC,您希望sum并行汇总3个字段。目前的内置功能无法做到这一点。我推荐最好的,可能是唯一的选择而不诉诸任何其他库:for循环。

total1 = total2 = total3 = 0

for x in your_list:
    total1 += x.field1
    total2 += x.field2
    total3 += x.field3

如果您想获得广告素材,并考虑到未知数量的属性,则可以使用dict来存储总计,并使用getattr来动态访问字段。

fields = ['field1', 'field2', 'field3'] # keep in mind these are the string names of your fields
total_dict = {f : 0 for f in fields}

for x in your_list:
    for f in fields:
        total_dict[f] += getattr(x, f)

这仍然是大致线性的,因为内环的大小是恒定的。

如果你想sum在一行中,我担心这是不可能的,除非你去像numpy这样的数字运算库。

import numpy as np
numbers = np.array([[x.field1, x.field2, x.field3] for x in your_list])

sum = numbers.sum(axis=0)

一个例子:

In [1316]: numbers = np.array([[1, 2, 3], [1, 2, 3], [1, 2, 3]])

In [1317]: numbers.sum(axis=0)
Out[1317]: array([3, 6, 9])

答案 1 :(得分:0)

sum函数只返回一个数字。也许你可以编写一个函数来返回许多数字:

def my_sum(l, fields):   
  _my_sum = lambda l, f: sum(getattr(i, f) for i in l)   
  return tuple(_my_sum(l, f) for f in fields)

total1, total2, total3 = my_sum(l, ["field1", "field2", "field3"])

答案 2 :(得分:0)

如果你在某种程度上反对在这里使用显式循环并且不想依赖其他第三方库,那么你可以采用功能性方法并使用类似functools.reduce()的东西。

from functools import reduce
total1, total2, total3 = reduce(
    lambda x, y: (x[0]+y.field1, x[1]+y.field2, x[2]+y.field3),
    items,
    (0,0,0)
)