2013-08-27 72 views
5

所以我有一個字典列表,像這樣:在Python中整合重複項時對詞典列表進行排序?

data = [ { 
      'Organization' : '123 Solar', 
      'Phone' : '444-444-4444', 
      'Email' : '', 
      'website' : 'www.123solar.com' 
     }, { 
      'Organization' : '123 Solar', 
      'Phone' : '', 
      'Email' : '[email protected]', 
      'Website' : 'www.123solar.com' 
     }, { 
      etc... 
     } ] 

當然,這不是確切的數據。但是(可能)從我的例子來看,你可以理解我的問題。我有許多具有相同「組織」名稱的記錄,但其中沒有一個具有該記錄的完整信息。

是否有想要搜索的列表,排序基於字典的第一個條目列表,終於從副本合併數據創建一個獨特的進入高效方法? (請記住這些字典是相當大)

回答

3

您可以使用itertools.groupby

from itertools import groupby 
from operator import itemgetter 
from pprint import pprint 

data = [ { 
      'Organization' : '123 Solar', 
      'Phone' : '444-444-4444', 
      'Email' : '', 
      'website' : 'www.123solar.com' 
     }, { 
      'Organization' : '123 Solar', 
      'Phone' : '', 
      'Email' : '[email protected]', 
      'Website' : 'www.123solar.com' 
     }, 
     { 
      'Organization' : '234 test', 
      'Phone' : '111', 
      'Email' : '[email protected]', 
      'Website' : 'b.123solar.com' 
     }, 
     { 
      'Organization' : '234 test', 
      'Phone' : '222', 
      'Email' : '[email protected]', 
      'Website' : 'bd.123solar.com' 
     }] 


data = sorted(data, key=itemgetter('Organization')) 
result = {} 
for key, group in groupby(data, key=itemgetter('Organization')): 
    result[key] = [item for item in group] 

pprint(result) 

打印:

{'123 Solar': [{'Email': '', 
       'Organization': '123 Solar', 
       'Phone': '444-444-4444', 
       'website': 'www.123solar.com'}, 
       {'Email': '[email protected]', 
       'Organization': '123 Solar', 
       'Phone': '', 
       'Website': 'www.123solar.com'}], 
'234 test': [{'Email': '[email protected]', 
       'Organization': '234 test', 
       'Phone': '111', 
       'Website': 'b.123solar.com'}, 
       {'Email': '[email protected]', 
       'Organization': '234 test', 
       'Phone': '222', 
       'Website': 'bd.123solar.com'}]} 

UPD:

這裏是你可以做的到組什麼商品成單字代碼:

for key, group in groupby(data, key=itemgetter('Organization')): 
    result[key] = {'Phone': [], 
        'Email': [], 
        'Website': []} 
    for item in group: 
     result[key]['Phone'].append(item['Phone']) 
     result[key]['Email'].append(item['Email']) 
     result[key]['Website'].append(item['Website']) 

然後,在result你必須:

{'123 Solar': {'Email': ['', '[email protected]'], 
       'Phone': ['444-444-4444', ''], 
       'Website': ['www.123solar.com', 'www.123solar.com']}, 
'234 test': {'Email': ['[email protected]', '[email protected]'], 
       'Phone': ['111', '222'], 
       'Website': ['b.123solar.com', 'bd.123solar.com']}} 
+0

我測試了你的代碼,它不完全是我所需要的。謝謝你給我看這種感覺,真是太棒了。我正在尋找一種方法將具有相同組織名稱的所有字典合併到同一個列表中的一個字典中。 –

+0

當然,你可以從這一個字典。只需使用那個'group'變量即可。 – alecxe

+0

@ Jacob-IT,我已經更新了答案,請檢查。 – alecxe

2

是否有從副本創建搜索在列表中,基於字典的第一個條目排序列表中,最後合併數據的有效方法一個獨特的條目?

是的,但有一個更有效的方法沒有搜索和排序。

datadict = {} 
for thingy in data: 
    organization = thingy['Organization'] 
    datadict[organization] = merge(thingy, datadict.get(organization, {})) 

現在你已經做了該數據的線性調整,做了每一個恆定的時間查找:你走只是建立一個字典。所以,它比任何排序的解決方案都要好O(log N)。這也是一次傳球而不是多次傳球,而且可能會有更低的常量開銷。


目前尚不清楚究竟你想要做合併條目什麼,有任何人都沒有辦法可以編寫代碼不知道你想用什麼樣的規則。但這裏有一個簡單的例子:

def merge(d1, d2): 
    for key, value in d2.items(): 
     if not d1.get(key): 
      d1[key] = value 
    return d1 

換句話說,在d2每個項目,如果d1已經有一個truthy值(如非空字符串),息事寧人;否則,添加它。

+0

您對「合併」功能有任何建議嗎? –

+0

這是簡單的部分;我以爲你已經知道如何做到這一點。但是我將編輯答案來展示一個例子: – abarnert

+0

我是Python的新手。如果我看起來很笨的話。 –

相關問題