我需要重新组织列表中的两个列表,并找到每个键值总和的总和。
list1 = [[a,b,c],[a,b,c],[a,b,c],[a,b,c],[b,c],[b,c],[a,c],[a,c],[b],[b],[d],[d]]
list2 = [[3,5,2],[-5,-2,-3],[12,11,8],[-8,-7,-5],[2,3],[-3,-2],[23,21],[-12,-22],[11],[-11],[22],[-21]]
list1是"字符串"的列表(关键)(例如" d71de5eb-18d9-4e85-9033-01be046f072e") list2只是整数(值)
新列表(我正在寻找的内容):
list1new = [a,b,c,d]
list2new = [13,6,2,1]
答案 0 :(得分:0)
您的并行列表确实无法帮助您解决这个问题。诀窍是将列表展平并将它们压缩成字典,将字符串映射到值列表。 itertools
和collections
可以提供帮助。
>>> a, b, c, d = 'abcd' >>> list1 = [[a,b,c],[a,b,c],[a,b,c],[a,b,c],[b,c],[b,c],[a,c],[a,c],[b],[b],[d],[d]]
>>> list2 = [[3,5,2],[-5,-2,-3],[12,11,8],[-8,-7,-5],[2,3],[-3,-2],[23,21],[-12,-22],[11],[-11],[22],[-21]]
>>> import collections
>>> import itertools
>>> elems1 = itertools.chain.from_iterable(list1)
>>> elems2 = itertools.chain.from_iterable(list2)
>>> d = collections.defaultdict(list)
>>> for key, value in zip(elems1, elems2):
... d[key].append(value)
...
>>> for k, lst in d.items():
... print k, sum(lst)
...
a 13
c 2
b 6
d 1
答案 1 :(得分:0)
您可以使用itertools.groupby
和itertools.chain
:
>>> from itertools import chain , groupby
>>> s=[zip(*i) for i in zip(list1,list2)]
>>> [(set(i).pop(),sum(j)) for i,j in [zip(*i) for i in [list(g) for _,g in groupby(sorted(chain(*s)),lambda x : x[0])]]]
[('a', 13), ('b', 6), ('c', 2), ('d', 1)]
或以更加pythonic的方式使用collections.defaultdict
:
>>> from collections import defaultdict
>>> from itertools import chain
>>> d=defaultdict(list)
>>> for k,v in zip(chain(*list1),chain(*list2)):
... d[k].append(v)
...
>>> [(k,sum(v)) for k,v in d.items()]
[('a', 13), ('c', 2), ('b', 6), ('d', 1)]
演示:
首先,您可以zip
列表获取以下内容:
>>> zip(list1,list2)
[(['a', 'b', 'c'], [3, 5, 2]), (['a', 'b', 'c'], [-5, -2, -3]), (['a', 'b', 'c'], [12, 11, 8]), (['a', 'b', 'c'], [-8, -7, -5]), (['b', 'c'], [2, 3]), (['b', 'c'], [-3, -2]), (['a', 'c'], [23, 21]), (['a', 'c'], [-12, -22]), (['b'], [11]), (['b'], [-11]), (['d'], [22]), (['d'], [-21])]
现在您需要将所有元组压缩在一起,因此您可以使用s=[zip(*i) for i in zip(list1,list2)]
执行此操作:
[[('a', 3), ('b', 5), ('c', 2)], [('a', -5), ('b', -2), ('c', -3)], [('a', 12), ('b', 11), ('c', 8)], [('a', -8), ('b', -7), ('c', -5)], [('b', 2), ('c', 3)], [('b', -3), ('c', -2)], [('a', 23), ('c', 21)], [('a', -12), ('c', -22)], [('b', 11)], [('b', -11)], [('d', 22)], [('d', -21)]]
然后您需要链接所有内部列表以进行排序和分组,因此您可以使用itertool.chain
:
>>> t=sorted(chain(*s))
>>> t
[('a', -12), ('a', -8), ('a', -5), ('a', 3), ('a', 12), ('a', 23), ('b', -11), ('b', -7), ('b', -3), ('b', -2), ('b', 2), ('b', 5), ('b', 11), ('b', 11), ('c', -22), ('c', -5), ('c', -3), ('c', -2), ('c', 2), ('c', 3), ('c', 8), ('c', 21), ('d', -21), ('d', 22)]
现在根据元组的第一个元素对上面的列表进行分组,你可以获得以下内容:
>>> [list(g) for _,g in groupby(t,lambda x : x[0])]
[[('a', -12), ('a', -8), ('a', -5), ('a', 3), ('a', 12), ('a', 23)], [('b', -11), ('b', -7), ('b', -3), ('b', -2), ('b', 2), ('b', 5), ('b', 11), ('b', 11)], [('c', -22), ('c', -5), ('c', -3), ('c', -2), ('c', 2), ('c', 3), ('c', 8), ('c', 21)], [('d', -21), ('d', 22)]]
然后你可以压缩前面结果的嵌套列表:
>>> a=[zip(*i) for i in [list(g) for _,g in groupby(t,lambda x : x[0])]]
[[('a', 'a', 'a', 'a', 'a', 'a'), (-12, -8, -5, 3, 12, 23)], [('b', 'b', 'b', 'b', 'b', 'b', 'b', 'b'), (-11, -7, -3, -2, 2, 5, 11, 11)], [('c', 'c', 'c', 'c', 'c', 'c', 'c', 'c'), (-22, -5, -3, -2, 2, 3, 8, 21)], [('d', 'd'), (-21, 22)]]
最后你需要它得到ziped元素的第一个索引的set
和第二个元素的总和:
>>> [(set(i),sum(j)) for i,j in a]
[(set(['a']), 13), (set(['b']), 6), (set(['c']), 2), (set(['d']), 1)]
使用pop()
获取set
。