5

だから私は次のような辞書のリストを持っています:

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

もちろん、これは正確なデータではありません。しかし、(おそらく) ここでの私の例から、私の問題を見つけることができます。同じ「組織」名のレコードが多数ありますが、そのレコードの完全な情報を持っているレコードはありません。

リストを検索し、辞書の最初のエントリに基づいてリストをソートし、最後に重複からデータをマージして一意のエントリを作成するための効率的な方法はありますか? (これらの辞書は非常に大きいことに注意してください)

4

2 に答える 2

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' : 'joey@123solar.com',
           'Website' : 'www.123solar.com'
         },
         {
           'Organization' : '234 test',
           'Phone' : '111',
           'Email' : 'a@123solar.com',
           'Website' : 'b.123solar.com'
         },
         {
           'Organization' : '234 test',
           'Phone' : '222',
           'Email' : 'ac@123solar.com',
           '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': 'joey@123solar.com',
                'Organization': '123 Solar',
                'Phone': '',
                'Website': 'www.123solar.com'}],
 '234 test': [{'Email': 'a@123solar.com',
               'Organization': '234 test',
               'Phone': '111',
               'Website': 'b.123solar.com'},
              {'Email': 'ac@123solar.com',
               'Organization': '234 test',
               'Phone': '222',
               'Website': 'bd.123solar.com'}]}

更新:

アイテムを単一の辞書にグループ化するためにできることは次のとおりです。

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': ['', 'joey@123solar.com'],
               'Phone': ['444-444-4444', ''],
               'Website': ['www.123solar.com', 'www.123solar.com']},
 '234 test': {'Email': ['a@123solar.com', 'ac@123solar.com'],
              'Phone': ['111', '222'],
              'Website': ['b.123solar.com', 'bd.123solar.com']}}
于 2013-08-27T19:23:33.720 に答える
2

リストを検索し、辞書の最初のエントリに基づいてリストをソートし、最後に重複からデータをマージして一意のエントリを作成するための効率的な方法はありますか?

はい。ただし、検索と並べ替えを行わないさらに効率的な方法があります。進めながら辞書を作成するだけです。

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

これで、データに対して線形パスを作成し、各データに対して一定時間のルックアップを実行しました。したがって、O(log N) の係数で並べ替えられたソリューションよりも優れています。また、複数のパスではなく1つのパスであり、おそらく一定のオーバーヘッドが少なくなります。


エントリをマージするために何をしたいのかが明確ではありません。また、使用するルールを知らずにコードを書くことはできません。しかし、ここに簡単な例があります:

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

つまり、 の各項目について、 (空でない文字列などの) 真の値が既にあるd2場合は、そのままにしておきます。d1それ以外の場合は追加します。

于 2013-08-27T19:24:26.543 に答える