簡體   English   中英

組合列表中的列表元素

[英]combining list elements in a list

我是python新用戶,我需要有關在一定條件下組合列表元素的幫助。 我有一個這樣的清單:

x = [['a', 10, 20], ['b', 10, 20], ['a', 20, 100]]

我想通過匯總其他元素來組合以相同字母開頭的列表元素。 例如,我想獲得x列表:

x = [['a', 30, 120], ['b', 10, 20]]

我該如何實現?

使用itertools.groupby()的單線

In [45]: lis=[['a', 10, 20], ['b', 10, 20], ['a', 20, 100]]

In [46]: lis.sort(key=itemgetter(0)) #sort the list first

In [47]: lis
Out[47]: [['a', 10, 20], ['a', 20, 100], ['b', 10, 20]]

In [49]: [[k]+map(sum,zip(*[x[1:] for x in g])) for k,g in groupby(lis,key=itemgetter(0))]
Out[49]: [['a', 30, 120], ['b', 10, 20]]

一個簡單的解決方案:

In [23]: lis=[['a', 10, 20], ['b', 10, 20], ['a', 20, 100]]

In [24]: ans=[]

In [25]: lis.sort(key=itemgetter(0))   #sort the list according to the first elem

In [26]: lis
Out[26]: [['a', 10, 20], ['a', 20, 100], ['b', 10, 20]]

In [27]: for x in lis:
    if ans:
        if x[0]==ans[-1][0]:  #if the value of the first elem of last element in ans is same as x[0]
            ans[-1][1]+=x[1]
            ans[-1][2]+=x[2]
        else:         
            ans.append(x)
    else:ans.append(x)
   ....:     

In [28]: ans
Out[28]: [['a', 30, 120], ['b', 10, 20]]

不使用defaultdict()對列表進行排序:

In [69]: dic=defaultdict(list)

In [70]: for x in lis:
    dic[x[0]].append(x[1:])
   ....:     

In [71]: dic
Out[71]: defaultdict(<type 'list'>, {'a': [[10, 20], [20, 100]], 'b': [[10, 20]]})

In [72]: [[k]+map(sum,zip(*i)) for k,i in dic.items()]
Out[72]: [['a', 30, 120], ['b', 10, 20]]

另一種使用dictmap

>>> x = [['a', 10, 20], ['b', 10, 20], ['a', 20, 100]]
>>> d = {}
>>> from operator import add
>>> for k, v1, v2 in x:
    d[k] = map(add, d.get(k, [0, 0]), [v1, v2])

>>> d
{'a': [30, 120], 'b': [10, 20]}

我將使用答案代碼處理包含超過millons元素的巨大數據。 我想用這種方式減少list元素。

在這種情況下,您可能不想在對數據進行迭代時對數據進行排序或構建完整副本。

以下解決方案都不起作用。 它也可以處理任何長度的子列表(只要所有長度都相同):

def add(d, l):
   k = l[0]            # extract the key
   p = d.get(k, None)  # see if we already have a partial sum for this key
   if p:
      d[k] = [x+y for x,y in zip(p, l[1:])] # add to the previous sum
   else:
      d[k] = l[1:]     # create a new sum
   return d

x = [['a', 10, 20], ['b', 10, 20], ['a', 20, 100]]
result = [[k] + v for k,v in reduce(add, x, {}).items()]
print(result)

或者,

import collections, operator

x = [['a', 10, 20], ['b', 10, 20], ['a', 20, 100]]

d = collections.defaultdict(lambda:[0] * (len(x[0]) - 1))
for el in x:
  d[el[0]] = map(operator.add, d[el[0]], el[1:])
result = [[k] + v for k,v in d.items()]
print(result)

它的工作原理與第一個版本完全相同,但是使用defaultdict和顯式迭代。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM