2016-09-17 6 views
3

簡単にするために、私は2つのリストをリストに入れましたが、実際にリストの100のリストを扱っています。私はそのリストの中の他の辞書をチェックすることなく(それらがすべてそのキーで同じ値を含んでいることを知っているので)第1の辞書の 'status'キーの値を得たいだけです。それから私は大きな辞書の中である種のクラスタリングを行います。私はすべての 'タイトル'の値を効率的に連結する必要があります。私のコードをもっとエレガントでもっと速くする方法はありますか?辞書のリストがもっと速く、もっと「平凡」である

私が持っている:

nested = [ 
    [ 
     {'id': 287, 'title': 'hungry badger', 'status': 'High'}, 
     {'id': 437, 'title': 'roadtrip to Kansas','status': 'High'} 
    ], 
    [ 
     {'id': 456, 'title': 'happy title here','status': 'Medium'}, 
     {'id': 342,'title': 'soft big bear','status': 'Medium'} 
    ] 
] 

私がしたい:

result = [ 
    { 
     'High': [ 
      {'id': 287, 'title': 'hungry badger'}, 
      {'id': 437, 'title': 'roadtrip to Kansas'} 
     ] 
    }, 
    { 
     'Medium': [ 
      {'id': 456, 'title': 'happy title here'}, 
      {'id': 342, 'title': 'soft big bear'} 
     ] 
    } 
] 

私が試したもの:

for oneList in nested: 
    result= {} 
    for i in oneList:   
     a= list(i.keys()) 
     m= [i[key] for key in a if key not in ['id','title']] 
     result[m[0]]=oneList 
     for key in a: 
      if key not in ['id','title']: 
       del i[key] 

答えて

2
from itertools import groupby  
result = groupby(sum(nested,[]), lambda x: x['status']) 

仕組み:

sum(nested,[])あなたがしたいので、もしitertools.groupbyは、発電機(ないリスト)を返し、ステータスプロパティ

注による辞書の一つの大きなリストに一緒に連結し、すべての外側のリスト

groupby(, lambda x: x['status'])グループすべてのオブジェクト次のような何かをする必要があるジェネレータを具体化する。

from itertools import groupby  
result = groupby(sum(nested,[]), lambda x: x['status']) 
result = {key:list(val) for key,val in result} 
+0

OMG! @。@ ワオ。あなたはとても速いです。とてもありがとう!!!!完璧に動作します。 – el347

+1

1: 'sum(nested、[])'は使わないでください。フラット化するのが最も遅い方法です。フラット化するほど遅くなります(毎回増えていく「一時的なリスト」を作成しています)。あなたはすでに 'itertools'を使っていますし、結果を反復しています(真の' list'は必要ありません)ので、 'itertools.chain.from_iterable'を使って平坦化してください(' lambda'は悪です/必要がない場合は遅く、 'key'の場合は' operator.itemgetter'): 'groupby(chain.from_iterable(ネストされた)、itemgetter( 'ステータス'))'。 ['sum(x、[])'は_slow_です(コメントを参照)](http://stackoverflow.com/a/39520827/364696)。 – ShadowRanger

+1

@ShadowRangerありがとう!ちょうどこれを実行しました:itertoolsインポートチェーンから; インポート演算子。 s = groupby(chain.from_iterable(results)、key = operator.itemgetter( 'status')); for key、grp in s:print(key、list(grp))良い。 – el347

2

あなたは、各ネストされたリストのためのdefaultdictを作ることができる:

import collections 
nested = [ 
[{'id': 287, 'title': 'hungry badger', 'status': 'High'}, 
{'id': 437, 'title': 'roadtrip to Kansas','status': 'High'}],  
[{'id': 456, 'title': 'happy title here','status': 'Medium'}, 
{'id': 342,'title': 'soft big bear','status': 'Medium'}] ] 
result = [] 
for l in nested: 
    r = collections.defaultdict(list) 
    for d in l: 
     name = d.pop('status') 
     r[name].append(d) 
    result.append(r) 

これは、次のresultを与える:

>>> import pprint 
>>> pprint.pprint(result) 
[{'High': [{'id': 287, 'title': 'hungry badger'}, 
      {'id': 437, 'title': 'roadtrip to Kansas'}]}, 
{'Medium': [{'id': 456, 'title': 'happy title here'}, 
      {'id': 342, 'title': 'soft big bear'}]}] 
+0

Tnx!ここで毎日新しいことを学ぶ。 Hehe。 itertoolsのgroupbyソリューションはとてもよく見えています。複雑さが軽減されます。あなたの答えは私にcollections.defaultdict()について教えてくれました。再度、感謝します。 – el347

+0

ああ素敵! Urソリューションはステータスを取り除き、私が求めていたことをします。私はこれらの両方の時間をちょうどそれのちょうどためにしても、もう少しitertools 'グループバイで遊ぶ...助けてくれ、ありがとう! – el347

関連する問題