2016-05-09 114 views
3

我的當前列表:合併列表

my_list = [ 
    {'id': 1, 'val': [6]}, 
    {'id': 2, 'val': [7]}, 
    {'id': 3, 'val': [8]}, 
    {'id': 2, 'val': [9]}, 
    {'id': 1, 'val': [10]}, 
] 

所需的輸出:

my_list = [ 
    {'id': 1, 'val': [6, 10]}, 
    {'id': 2, 'val': [7, 9]}, 
    {'id': 3, 'val': [8]}, 
] 

我試過到目前爲止:

my_new_list = [] 
    id_set = set() 

    for d in my_list: 
     if d['id'] not in id_set: 
      id_set.add(d['id']) 
      temp = {'id': d['id'], 'val': d['val']} 
      my_new_list.append(temp) 
     else: 
      # loop over the new list and find the dict which already have d['id'] and update by appending value 
      # but this is not efficient 

任何其他更有效的方法或者可能是我不知道的一些內置功能。

PS:順序很重要!

+0

在新的名單將有'id'獨特的價值,你可以使用字典來代替,用'id'作爲重點。這樣你就不必循環遍歷新列表,你可以直接通過id來訪問它。 – spectras

+0

輸出清單的順序是否重要? – schwobaseggl

+0

@schwobaseggl:是的順序是重要的,這就是爲什麼我沒有使用詞典提到的y spectras – Wendy

回答

4

.setdefault()是你的朋友:

(我們應該用collections.OrderedDict記住按鍵首先插入的順序)

>>> import collections 

>>> result = collections.OrderedDict() 
>>> for d in my_list: 
...  result.setdefault(d["id"], []).extend(d["val"]) 

>>> lst = [] 
>>> for k, v in result.items(): 
...  lst.append({"id": k, "val": v}) 
+0

第二部分的列表理解形式是非常可讀的,以及'lst = [{「id」:k,「val」:v } for k,v in result.items()]' – spectras

0

您可以使用itertools.groupby以進行排序和分組原list作者:'id'並累積各組的'val'

from itertools import groupby 

key_fnc = lambda d: d['id'] 
result = [ 
    {'id': k, 'val': sum([d['val'] for d in g], [])} 
     for k, g in groupby(sorted(my_list, key=key_fnc), key=key_fnc) 
] 
1

相同的方法ozgur,但使用collections.defaultdict

>>> from collections import defaultdict 
>>> d = defaultdict(list) 
>>> for dd in my_list: 
     d[dd['id']].extend(dd['val']) 
>>> d 
defaultdict(<type 'list'>, {1: [6, 10], 2: [7, 9], 3: [8]}) 
>>> 
>>> lst = [] 
>>> for k,v in d.iteritems(): 
     lst.append({'id':k, 'val':v}) 

>>> lst 
[{'id': 1, 'val': [6, 10]}, {'id': 2, 'val': [7, 9]}, {'id': 3, 'val': [8]}] 
>>> 
+0

順序對我很重要。我們可以使用'OrderedDict'來代替'defaultdict'。 – Wendy

+0

如果您從原始'my_list'訂購,那麼它會保持順序,因爲它正在迭代。 –