2012-02-20 17 views
2

私はさまざまなアイテムの束についての情報を持っているの不確定数を持っているすべての辞書を見つけます。各アイテムにはそのアイテムに関する情報が入った独自の辞書があり、各アイテムが格納されている大きな辞書があります。しかし、私は各項目について同じ情報を持っているわけではありません。たとえば、私の商品が果物だとしましょう。私はそれが定義されている各果実の起源を見つけたい場合はそれぞれが定義されているキー

fruit = {} 
fruit['apple'] = {'color': 'red', 'origin': 'Washington'} 
fruit['banana'] = {'color': 'yellow'} 
fruit['orange'] = {'color': 'orange', 'origin': 'Florida'} 

、私は次のことをやっている:そして、構造は次のようになります

fruits, origins = zip(* [(f, fruit[f]['origin']) for f in fruit.keys() if 'origin' in fruit[f]]) 

罰金に動作すること。私は、色と原点の両方が定義されているすべての果物を見つけたいと思うと、醜くなり始めます。私がやりたい何

fruits, origins, colors = zip(* [(f, fruit[f]['origin'], fruit[f]['color']) for f in fruit.keys() if 'origin' in fruit[f] and 'color' in fruit[f]]) 

は、指定されたキーの任意の数のこのアクションを実行する一般的な関数を書くことができるようです。それは、私が辞書の辞書を取るだろう「定義された」と呼ばれるいくつかの機能、およびサブディクショナリ内のキーのキーまたはリストを呼び出し、およびそれらのキーのそれぞれの定義を持つサブ辞書のすべてを返すことができ、あります各キーの値が表示されます。

fruits, origins = defined(fruit, ['origin']) 
fruits, origins, colors = defined(fruit, ['origin', 'color']) 

私は、辞書への外または中に、キー/値のペアを得ることについて疑問を持つ既存のスレッドの様々な見てきたが、私は右に見える何かを発見していません。これを一般化するのに合理的に簡単な方法はありますか?

それとも、人々はまた、私は完全に異なる方法で自分のデータを整理する必要があることを教えたい場合は、私もそれを歓迎します。私は当初、各項目に利用可能な情報の幅が広いため、辞書の辞書に着手しました。例えば、いくつかのサブ辞書が情報を持つエントリの数十を持っている、といくつかの項目はのみ(つまり、「りんご」辞書は多くの情報を持っていますが、私はずっと「キンカン」に保存されていません)いくつかのエントリを持っています。それは、すべての必要なフィールドを持っているすべての辞書のエントリに対して反復反復子を返します。ここでは

答えて

4

あなたはallでリストの内包によって値抽出、およびandシーケンスを一般化することができます

def defined(dct, keys): 
    return zip(*[([k] + [v[m] for m in keys]) 
       for k, v in dct.iteritems() 
       if all(m in v for m in keys)]) 
+0

偉大な、これは私が望んでいた方法と同じように働いた。ありがとうございました! – jdmcbr

2

呼び出しあなたの例で示唆さよりもわずかに異なる方法でデータを返す関数です。

def defined(fruits, attr_names): 
    getter = operator.itemgetter(*attr_names) 
    for f, d in fruit.iteritems(): 
     try: 
      attrs = getter(d) 
     except KeyError: 
      continue 
     else: 
      yield (f,) + attrs 

実装で唯一言及する価値のあるものはoperator.itemgetter()です。

operator.itemgetter(['origin', 'color']) 

ようなコールは、辞書に適用し、キー'origin'タプルとして'color'の値を返す関数を返します。鍵の1つが失われない場合、辞書はいつものようにKeyErrorを投げます。

あなたが提案した方法でこの機能を使用するために返されたイテレータに zip()を使用することができます

fruits, origins, colors = zip(*defined(fruit, ['origin', 'color'])) 
+0

ありがとう!これは私が与えたおもちゃの例のために働いた。なんらかの理由で、私は本当の問題のためにそれを働かせることはできませんが、私はこれをさらに続けて、これが何をしているのかを正確に理解しようとします。 – jdmcbr

関連する問題