嵌套列表根据第一个值组合值

时间:2018-01-07 10:45:35

标签: python-2.7 list nested-lists

list = [ ['a',14,2], ['b',10,1], ['a',3,12], ['r',5,5], ['r',6,13] ]
result = data_sum(list)

def data_sum(list):
  for set in list:
    current_index = list.index(set)
    string  = set[0]
    for item in list:
      second_index = list.index(each)
      if string == item[0] and current_index != second_index:
        set[0] = item[0]
        set[1] += item[1]
        set[2] += item[2]
        del each

  return list

我的结果应该是

[ ['a',17,14], ['b',10,1], ['r',11,18] ]

如果嵌套列表相同,则根据第一个字符串聚合嵌套列表。

我不认为我可以在这里使用set[],因为它不会根据嵌套列表本身内的元素进行总结。

  1. 我不确定我是否正确使用list.index
  2. 到目前为止,输出是完全相同的原始列表

1 个答案:

答案 0 :(得分:1)

首先,listsetstring已经内置了函数,因此不建议使用这些名称。我也认为你的问题稍微复杂一点,因为你需要做的就是将字母组合在一起,然后对这些值进行一些求和。

为了让自己更容易解决这个问题,你需要以某种方式对每个列表的第一个值进行分组,并在此之后获取值的总和。一种可能的方法是使用collections.defaultdict对第一个值进行分组,然后对相应的值求和:

from collections import defaultdict

lsts = [['a',14,2], ['b',10,1], ['a',3,12], ['r',5,5], ['r',6,13]]

groups = defaultdict(list)
for letter, first, second in lsts:
    groups[letter].append([first, second])
# defaultdict(<class 'list'>, {'a': [[14, 2], [3, 12]], 'b': [[10, 1]], 'r': [[5, 5], [6, 13]]})

result = []
for key, value in groups.items():
    sums = [sum(x) for x in zip(*value)]
    result.append([key] + sums)

print(result)

哪个输出:

[['a', 17, 14], ['b', 10, 1], ['r', 11, 18]]

结果列表也可以用这个列表理解来编写:

result = [[[key] + [sum(x) for x in zip(*value)]] for key, value in groups.items()]

另一种方法是使用itertools.groupby

from itertools import groupby
from operator import itemgetter

grouped = [list(g) for _, g in groupby(sorted(lsts), key = itemgetter(0))]
# [[['a', 3, 12], ['a', 14, 2]], [['b', 10, 1]], [['r', 5, 5], ['r', 6, 13]]]

result = []
for group in grouped:
    numbers = [x[1:] for x in group]
    sums = [sum(x) for x in zip(*numbers)]
    result.append([[group[0][0]] + sums])
print(result)

还输出:

[['a', 17, 14], ['b', 10, 1], ['r', 11, 18]]

注意:第二种方法也可以写成一个大列表理解:

result = [[[group[0][0]] + [sum(x) for x in zip(*[x[1:] for x in group])]] for group in [list(g) for _, g in groupby(sorted(lsts), key = itemgetter(0))]]

但这很丑陋且难以辨认,不应该使用。