2013-08-27 71 views
5

Vì vậy, tôi có một danh sách các từ điển như vậy:Sắp xếp danh sách các từ điển trong khi hợp nhất các bản sao trong 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... 
     } ] 

Tất nhiên, đây không phải là dữ liệu chính xác. Nhưng (có thể) từ ví dụ của tôi ở đây bạn có thể bắt gặp vấn đề của tôi. Tôi có nhiều hồ sơ với cùng tên "Tổ chức", nhưng không một trong số họ có thông tin đầy đủ cho hồ sơ đó.

Có một hiệu quả phương pháp để tìm kiếm trên danh sách, sắp xếp danh sách dựa trên của từ điển nhập đầu tiên, và cuối cùng kết hợp dữ liệu từ bản sao để tạo ra một độc đáo nhập? (Hãy ghi nhớ các bộ từ điển khá lớn)

Trả lời

3

Bạn có thể tận dụng 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) 

in:

{'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:

Dưới đây là những gì bạn có thể làm để nhóm các mục vào dict đơn lẻ:

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']) 

sau đó, trong result bạn sẽ có:

{'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

Tôi đã kiểm tra mã của bạn và không chính xác những gì tôi cần. Cảm ơn vì đã cho tôi thấy sự sắp xếp, điều đó thật tuyệt vời. Tôi đang tìm cách kết hợp tất cả các từ điển có cùng tên tổ chức thành một từ điển trong cùng một danh sách. –

+0

Chắc chắn, bạn có thể tạo một từ điển từ này. Chỉ cần sử dụng biến 'nhóm' đó. – alecxe

+0

@ Jacob-IT, tôi đã cập nhật câu trả lời, vui lòng kiểm tra. – alecxe

2

Có một phương pháp hiệu quả để tìm kiếm trên danh sách, sắp xếp danh sách dựa trên của từ điển nhập đầu tiên, và cuối cùng kết hợp dữ liệu từ bản sao để tạo ra một mục duy nhất?

Có, nhưng có một phương pháp hiệu quả hơn mà không cần tìm kiếm và sắp xếp. Chỉ cần xây dựng một từ điển khi bạn thực hiện:

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

Bây giờ bạn đã thực hiện tra cứu tuyến tính qua dữ liệu, thực hiện tra cứu liên tục cho từng dữ liệu. Vì vậy, nó tốt hơn so với bất kỳ giải pháp được sắp xếp bởi một yếu tố của O (log N). Nó cũng là một vượt qua thay vì nhiều lượt, và nó có lẽ sẽ có chi phí thấp hơn không đổi bên cạnh.


Không rõ chính xác bạn muốn làm gì để hợp nhất mục nhập và không ai có thể viết mã mà không biết bạn muốn sử dụng quy tắc nào. Nhưng đây là một ví dụ đơn giản:

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

Nói cách khác, đối với mỗi mục trong d2, nếu d1 đã có một giá trị truthy (như một chuỗi không trống), để lại một mình; nếu không, hãy thêm nó.

+0

Bạn có đề xuất nào về chức năng 'hợp nhất' không? –

+0

Đó là phần dễ dàng; Tôi cho rằng bạn đã biết cách làm điều đó.Nhưng tôi sẽ chỉnh sửa câu trả lời để hiển thị ví dụ: – abarnert

+0

Tôi mới sử dụng Python..xin lỗi nếu tôi có vẻ như không biết. –