Python lista de comprensión para los diccionarios en los diccionarios?

Acabo de aprender acerca de la comprensión de listas, que es una excelente manera rápida de obtener datos en una sola línea de código. Pero algo me está molestando.

En mi prueba tengo este tipo de diccionarios dentro de la lista:

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

La lista de comprensión s = [ r for r in list if r['x'] > 92 and r['x'] 70 and r['y'] < 75 ] funciona perfectamente en eso (es, de hecho, el resultado de esta línea)

De todos modos, me di cuenta de que en realidad no estoy usando una lista en mi otro proyecto, estoy usando un diccionario. Al igual que:

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

De esa manera simplemente puedo editar mi diccionario con var['test1420'] = ...

¡Pero la lista de comprensión no funciona en eso! Y no puedo editar las listas de esta manera porque no puedes asignar un índice como ese.

¿Hay otra manera?

Puedes hacerlo:

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

Esto toma un dict como especificó y devuelve un dict 'filtrado'.

Si dct es

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

Quizás estés buscando algo como:

 [ subdct for key,subdct in dct.iteritems() if 92 

Un poco de amabilidad es que Python te permite encadenar desigualdades:

 92 

en lugar de

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

Tenga en cuenta también que anteriormente he escrito una lista de comprensión, por lo que vuelve a obtener una lista (en este caso, de los dictados).

En Python3 hay cosas como las comprensiones de dictado también:

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

En Python2 el equivalente sería

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

No estoy seguro si está buscando una lista de dictados o dictados, pero si entiende los ejemplos anteriores, es fácil modificar mi respuesta para obtener lo que desea.

Suena como que quieres algo como:

 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) 

Algunas notas sobre este código:

  1. Estoy usando una expresión generadora en lugar de una lista de comprensión
  2. Python le permite combinar pruebas de desigualdad como low < value < high
  3. El constructor dict () toma un iterable de tuplas clave / valor para crear un diccionario

Puede obtener una lista de los valores de un diccionario d con d.values() . La comprensión de tu lista debería funcionar con eso, aunque no estoy muy claro qué es exactamente lo que quieres que sea la salida.

¿Hay otra manera?

¿Por qué no considerar el uso de algunos objetos ligeros?

Puede seguir utilizando las listas de comprensión para reunir o filtrar los objetos, y ganar mucho en claridad / extensibilidad.

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