>>> d = {"foo": 12, "bar": 2, "jim": 4, "bob": 17}
>>> [k for k, v in d.items() if v > 6] # Use d.iteritems() on python 2.x
['bob', 'foo']
me gustaría actualizar simplemente esta respuesta para exhibir también la solución por @glarrain que me encuentro que tiende a utilizar hoy en día.
[k for k in d if d[k] > 6]
Esto es completamente compatible cruz y no requiere un cambio confuso de .iteritems
(.iteritems
evita ahorro de una lista de memoria en Python 2 que se fija en Python 3) para .items
.
@ Prof.Falken mencionado una solución a este problema
from six import iteritems
que fija de manera efectiva los problemas de compatibilidad cruz, sino que requiere para descargar el paquete six
Sin embargo, no estaría de acuerdo plenamente con @glarrain que esta solución es más legible, eso es tema de debate y tal vez solo una preferencia personal, aunque se supone que Python tiene solo 1 forma de hacerlo. En mi opinión, depende de la situación (por ejemplo, puede tener un nombre de diccionario largo que no desea escribir dos veces o quiere dar a los valores un nombre más legible u otro motivo)
Algunos tiempos interesantes :
En Python 2, la segunda solución es más rápida, en Python 3 son casi exactamente iguales en velocidad bruta.
$ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.items() if v > 6]'
1000000 loops, best of 3: 0.772 usec per loop
$ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.iteritems() if v > 6]'
1000000 loops, best of 3: 0.508 usec per loop
$ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k in d if d[k] > 6]'
1000000 loops, best of 3: 0.45 usec per loop
$ python3 -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.items() if v > 6]'
1000000 loops, best of 3: 1.02 usec per loop
$ python3 -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k in d if d[k] > 6]'
1000000 loops, best of 3: 1.02 usec per loop
Sin embargo, estos son sólo pruebas para pequeños diccionarios, en enormes diccionarios Estoy bastante seguro de que no tener un diccionario de búsqueda de claves (d[k]
) haría .items
mucho más rápido. Y este parece ser el caso
$ python -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k in d if d[k] > 6]'
1 loops, best of 3: 1.75 sec per loop
$ python -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k, v in d.iteritems() if v > 6]'
1 loops, best of 3: 1.71 sec per loop
$ python3 -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k in d if d[k] > 6]'
1 loops, best of 3: 3.08 sec per loop
$ python3 -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k, v in d.items() if v > 6]'
1 loops, best of 3: 2.47 sec per loop
El título de esta pregunta debe ser modificado después de lo que realmente quiere lograr (y las respuestas reflejan esta) es obtener las claves de los valores correspondientes en un diccionario para el cual una determinada cláusula es verdadera. Algo así como "Cómo filtrar las claves del diccionario en función de sus valores correspondientes" podría ser una mejor alternativa. – glarrain