2013-08-27 2 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

Есть ли у вас предложения по функции 'merge'? –

+0

Это легкая часть; Я предположил, что ты уже знал, как это сделать.Но я отредактирую ответ, чтобы показать пример: – abarnert

+0

Я новичок в Python..извижу, если я, кажется, dunce. –

Смежные вопросы