Подтвердить что ты не робот

Python для понимания словарей в словарях?

Я только что узнал о понимании списка, что является отличным быстрым способом получения данных в одной строке кода. Но что-то меня пугает.

В моем тесте у меня есть такие словари внутри списка:

[{'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'] = ...

Но переписные справки на этом не работают! И я не могу редактировать списки таким образом, потому что вы не можете назначить такой индекс.

Есть ли другой способ?

4b9b3361

Ответ 1

Вы можете сделать это:

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

Это принимает dict, как вы указали, и возвращает "отфильтрованный" dict.

Ответ 2

Если 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 или dict dicts, но если вы понимаете приведенные выше примеры, легко изменить мой ответ, чтобы получить то, что вы хотите.

Ответ 3

Похоже, вы хотите что-то вроде:

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)

Некоторые примечания к этому коду:

  • Я использую выражение генератора вместо понимания списка.
  • Python позволяет комбинировать неравенство тесты как low < value < high
  • Конструктор dict() принимает итерабельную наборов ключей/значений для создания Словарь

Ответ 4

Вы можете получить список значений словаря d с помощью d.values(). Ваше понимание списка должно работать с этим, хотя я немного не понимаю, что именно вы хотите получить.

Ответ 5

Есть ли другой способ?

Почему бы не рассмотреть использование некоторых легких предметов?

Вы все еще можете использовать списки для сбора или фильтрации объектов и многого добиться в ясности/расширяемости.

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