Je viens d’apprendre la compréhension de liste, qui est un excellent moyen rapide d’obtenir des données dans une seule ligne de code. Mais quelque chose m'embête.
Dans mon test, j'ai ce genre de dictionnaires dans la liste:
[{'y': 72, 'x': 94, 'fname': 'test1420'}, {'y': 72, 'x': 94, 'fname': 'test277'}]
La compréhension de la liste s = [ r for r in list if r['x'] > 92 and r['x'] < 95 and r['y'] > 70 and r['y'] < 75 ]
fonctionne parfaitement sur celui-ci (il s’agit en fait du résultat de cette ligne)
Quoi qu'il en soit, j'ai alors réalisé que je n'utilisais pas vraiment une liste dans mon autre projet, mais un dictionnaire. Ainsi:
{'test1420': {'y': '060', 'x': '070', 'fname': 'test1420'}}
De cette façon, je peux simplement éditer mon dictionnaire avec var['test1420'] = ...
Mais la compréhension des listes ne fonctionne pas avec ça! Et je ne peux pas éditer des listes de cette façon parce que vous ne pouvez pas assigner un index comme ça.
Y a-t-il un autre moyen?
Tu peux le faire:
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 ])
Cela prend un dict comme vous l'avez spécifié et retourne un dict 'filtré'.
Si dct
est
{'test1420': {'y': '060', 'x': '070', 'fname': 'test1420'},
'test277': {'y': 72, 'x': 94, 'fname': 'test277'},}
Peut-être cherchez-vous quelque chose comme:
[ subdct for key,subdct in dct.iteritems()
if 92<subdct['x']<95 and 70<subdct['y']<75 ]
Un petit avantage est que Python vous permet de chaîner les inégalités:
92<dct[key]['x']<95
au lieu de
if r['x'] > 92 and r['x'] < 95
Notez également que ci-dessus j'ai écrit une liste de compréhension, donc vous obtenez une liste (dans ce cas, des dicts).
En Python3, il existe des choses telles que dict comprehensions ainsi:
{ n: n*n for n in range(5) } # dict comprehension
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
En Python2, l'équivalent serait
dict( (n,n*n) for n in range(5) )
Je ne sais pas si vous cherchez une liste de dictés ou un dicton de dictés, mais si vous comprenez les exemples ci-dessus, il est facile de modifier ma réponse pour obtenir ce que vous voulez.
On dirait que vous voulez quelque chose comme:
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)
Quelques notes sur ce code:
low < value < high
Vous pouvez obtenir une liste des valeurs d’un dictionnaire d avec d.values()
. Votre compréhension de liste devrait fonctionner avec cela, bien que je sois un peu incertain quant à ce que vous voulez exactement.
Y a-t-il un autre moyen?
Pourquoi ne pas envisager l'utilisation de certains objets légers?
Vous pouvez still utiliser des compréhensions de liste pour rassembler ou filtrer les objets, et gagner beaucoup en clarté/extensibilité.
>>> 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