Понимание списка Python для словарей в словарях? - PullRequest
21 голосов
/ 12 июля 2010

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

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

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

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

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

Ответы [ 5 ]

36 голосов
/ 12 июля 2010

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

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.

9 голосов
/ 12 июля 2010

Если 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

Обратите внимание, что выше я написал понимание списка, поэтому вы получите список (в данном случае, слова).

В Python3 есть такие вещи, как понимание слова :

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

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

2 голосов
/ 12 июля 2010

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

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 () принимает итеративный кортежей ключ / значение для создания словарь
0 голосов
/ 12 июля 2010

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

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

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

0 голосов
/ 12 июля 2010

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

...