Ответ 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.
Я только что узнал о понимании списка, что является отличным быстрым способом получения данных в одной строке кода. Но что-то меня пугает.
В моем тесте у меня есть такие словари внутри списка:
[{'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'] = ...
Но переписные справки на этом не работают! И я не могу редактировать списки таким образом, потому что вы не можете назначить такой индекс.
Есть ли другой способ?
Вы можете сделать это:
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.
Если 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, но если вы понимаете приведенные выше примеры, легко изменить мой ответ, чтобы получить то, что вы хотите.
Похоже, вы хотите что-то вроде:
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)
Некоторые примечания к этому коду:
low < value < high
Вы можете получить список значений словаря d с помощью d.values()
. Ваше понимание списка должно работать с этим, хотя я немного не понимаю, что именно вы хотите получить.
Есть ли другой способ?
Почему бы не рассмотреть использование некоторых легких предметов?
Вы все еще можете использовать списки для сбора или фильтрации объектов и многого добиться в ясности/расширяемости.
>>> 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