web-dev-qa-db-ja.com

Python辞書内の辞書の理解度をリストしますか?

リスト内包について学びました。これは、1行のコードでデータを取得するための非常に高速な方法です。しかし、何かが私を悩ませています。

私のテストでは、リスト内に次の種類の辞書があります。

[{'y': 72, 'x': 94, 'fname': 'test1420'}, {'y': 72, 'x': 94, 'fname': 'test277'}]

リスト内包表記s = [ r for r in list if r['x'] > 92 and r['x'] < 95 and r['y'] > 70 and r['y'] < 75 ]はその上で完全に機能します(実際、この行の結果です)

とにかく、他のプロジェクトのリストを実際に使用しているのではなく、辞書を使用していることに気付きました。そのようです:

{'test1420': {'y': '060', 'x': '070', 'fname': 'test1420'}}

そうすれば、var['test1420'] = ...で辞書を編集できます

しかし、リスト内包表記はそれでは機能しません!このようにインデックスを割り当てることができないため、この方法でリストを編集することはできません。

別の方法はありますか?

21
skerit

あなたはこれを行うことができます:

s = dict([ (k,r) for k,r in mydict.iteritems() if r['x'] > 92 and r['x'] < 95 and r['y'] > 70 and r['y'] < 75 ])

これは、指定した辞書を受け取り、「フィルター処理された」辞書を返します。

36
adamk

dct

{'test1420': {'y': '060', 'x': '070', 'fname': 'test1420'},
 'test277': {'y': 72, 'x': 94, 'fname': 'test277'},}

おそらくあなたは次のようなものを探しています:

[ subdct for key,subdct in dct.iteritems() 
  if 92<subdct['x']<95 and 70<subdct['y']<75 ]

Python=を使用すると、不等式を連鎖させることができます。

92<dct[key]['x']<95

の代わりに

if r['x'] > 92 and r['x'] < 95

また、上記ではリスト内包表記を記述しているため、リスト(この場合は、dicts)が返されることにも注意してください。

Python3には dict comprehensions のようなものもあります:

{ n: n*n for n in range(5) } # dict comprehension
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

Python2では、同等のものは

dict( (n,n*n) for n in range(5) )

Dictsのリストを探しているのか、dicts of dictsを探しているのかはわかりませんが、上記の例を理解していれば、私の答えを簡単に変更して目的のものを取得できます。

9
unutbu

あなたは次のようなものが欲しいようです:

my_dict = {'test1420': {'y': '060', 'x': '070', 'fname': 'test1420'},
           'test277' : {'y': '072', 'x': '094', 'fname': 'test277'}}


new_dict = dict((k,v) for k,v in my_dict.items() 
                    if 92 < int(v['x']) < 95 and 70 < int(v['y']) < 75)

このコードに関する注意事項:

  1. リスト内包表記の代わりにジェネレータ式を使用しています
  2. Pythonでは、不等式テストをlow < value < highとして組み合わせることができます
  3. Dict()コンストラクターは、反復可能なキー/値タプルを取得して辞書を作成します
2
Triptych

d.values()を使用して、辞書dの値のリストを取得できます。リストの理解はそれを使用して機能するはずですが、出力を正確に何にしたいのかは少しわかりません。

0
Rob Lourens

別の方法はありますか?

いくつかの軽量オブジェクトの使用を考えてみませんか?

オブジェクトを収集またはフィルタリングするためにリスト内包表記を使用してstillし、明確性/拡張性を大幅に向上させることができます。

>>> class Item(object):
...     def __init__(self, x, y, name):
...         self.x = x
...         self.y = y
...         self.name = name
... 
>>> list_items = []
>>> list_items.append(Item(x=70, y=60, name='test1420'))                        
>>> list_items.append(Item(x=94, y=72, name='test277'))                         
>>> items_matching = [item for item in list_items 
                      if 92 < item.x < 95 and 70 < item.y < 75]
>>> for item in items_matching:
...     print item.name
... 
test277
>>> first_item = items_matching[0]
>>> first_item.x += 50
>>> first_item.x
144
0
ChristopheD