重新组织列表python中的列表

时间:2014-12-30 16:50:19

标签: python list key

我需要重新组织列表中的两个列表,并找到每个键值总和的总和。

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]

2 个答案:

答案 0 :(得分:0)

您的并行列表确实无法帮助您解决这个问题。诀窍是将列表展平并将它们压缩成字典,将字符串映射到值列表。 itertoolscollections可以提供帮助。

>>> 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.groupbyitertools.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

元素