¿El filtro dict para contener solamente ciertas claves?

Tengo un dict que tiene un montón de entradas. Sólo estoy interesado en unos pocos seleccionados. ¿Hay una manera fácil de podar todos los demás?

Construyendo un nuevo dictado:

 dict_you_want = { your_key: old_dict[your_key] for your_key in your_keys } 

Utiliza la comprensión del diccionario.

Si usa una versión que no los tiene (es decir, Python 2.6 y anteriores), haga que dict((your_key, old_dict[your_key]) for ...) . Es lo mismo, aunque más feo.

Tenga en cuenta que esto, a diferencia de la versión de jnnnnn, tiene un rendimiento estable (depende solo del número de teclas your_) para old_dict s de cualquier tamaño. Tanto en términos de velocidad como de memoria. Dado que esta es una expresión generadora, procesa un elemento a la vez y no examina todos los elementos de old_dict.

Eliminando todo en el lugar:

 unwanted = set(keys) - set(your_dict) for unwanted_key in unwanted: del your_dict[unwanted_key] 

Un poco más elegante comprensión de dict:

 foodict = {k: v for k, v in mydict.items() if k.startswith('foo')} 

Aquí hay un ejemplo en Python 2.6:

 >>> a = {1:1, 2:2, 3:3} >>> dict((key,value) for key, value in a.iteritems() if key == 1) {1: 1} 

La parte de filtrado es la sentencia if .

Este método es más lento que la respuesta de Delnan si solo desea seleccionar algunas de las muchas claves.

Puedes hacer eso con la función de proyecto de mi librería funcy :

 from funcy import project small_dict = project(big_dict, keys) 

También eche un vistazo a select_keys .

Este forro lambda debería funcionar:

 dictfilt = lambda x, y: dict([ (i,x[i]) for i in x if i in set(y) ]) 

Aquí hay un ejemplo:

 my_dict = {"a":1,"b":2,"c":3,"d":4} wanted_keys = ("c","d") # run it In [10]: dictfilt(my_dict, wanted_keys) Out[10]: {'c': 3, 'd': 4} 

Es una lista de comprensión básica que recorre las teclas de dictado (i en x) y genera una lista de pares de tuplas (clave, valor) si la clave se encuentra en la lista de claves deseada (y). Un dict () envuelve todo para dar salida como un objeto dict.

Dado el origen de su diccionario original y el conjunto de entradas que le interesan en las keys :

 filtered = dict(zip(keys, [orig[k] for k in keys])) 

que no es tan agradable como la respuesta de Delnan, pero debería funcionar en todas las versiones de Python de interés. Sin embargo, es frágil para cada elemento de las keys existentes en su diccionario original.

Código 1:

 dict = { key: key * 10 for key in range(0, 100) } d1 = {} for key, value in dict.items(): if key % 2 == 0: d1[key] = value 

Código 2:

 dict = { key: key * 10 for key in range(0, 100) } d2 = {key: value for key, value in dict.items() if key % 2 == 0} 

Código 3:

 dict = { key: key * 10 for key in range(0, 100) } d3 = { key: dict[key] for key in dict.keys() if key % 2 == 0} 

Todas las piezas del rendimiento del código se miden con timeit usando number = 1000, y se recostackn 1000 veces para cada pieza de código.

introduzca la descripción de la imagen aquí

Para Python 3.6, el rendimiento de tres formas de filtrado de claves de dictado es casi el mismo. Para Python, el código 3 es un poco más rápido.

Basado en la respuesta aceptada por delnan.

¿Qué pasa si una de tus claves buscadas no está en el old_dict? La solución de delnan lanzará una excepción KeyError que puede capturar. Si eso no es lo que necesitas quizás quieras:

  1. solo incluye claves que exista tanto en el old_dict como en tu conjunto de wanted_keys.

     old_dict = {'name':"Foobar", 'baz':42} wanted_keys = ['name', 'age'] new_dict = {k: old_dict[k] for k in set(wanted_keys) & set(old_dict.keys())} >>> new_dict {'name': 'Foobar'} 
  2. tiene un valor predeterminado para las claves que no están establecidas en old_dict.

     default = None new_dict = {k: old_dict[k] if k in old_dict else default for k in wanted_keys} >>> new_dict {'age': None, 'name': 'Foobar'} 

Esta función hará el truco:

 def include_keys(dictionary, keys): """Filters a dict by only including certain keys.""" key_set = set(keys) & set(dictionary.keys()) return {key: dictionary[key] for key in key_set} 

Al igual que la versión de Delnan, este utiliza la comprensión del diccionario y tiene un rendimiento estable para los diccionarios grandes (depende solo de la cantidad de claves que usted permita, y no del número total de claves en el diccionario).

Y al igual que la versión de MyGGan, esta permite que su lista de claves incluya claves que pueden no existir en el diccionario.

Y como beneficio adicional, aquí está la inversa, donde puede crear un diccionario al excluir ciertas claves en el original:

 def exclude_keys(dictionary, keys): """Filters a dict by excluding certain keys.""" key_set = set(dictionary.keys()) - set(keys) return {key: dictionary[key] for key in key_set} 

Tenga en cuenta que, a diferencia de la versión de Delnan, la operación no se realiza en su lugar, por lo que el rendimiento está relacionado con el número de claves en el diccionario. Sin embargo, la ventaja de esto es que la función no modificará el diccionario proporcionado.

Edición: Se agregó una función separada para excluir ciertas teclas de un dict.

Forma corta:

 [s.pop(k) for k in list(s.keys()) if k not in keep] 

Como la mayoría de las respuestas sugieren para mantener la concisión, tenemos que crear un objeto duplicado, ya sea una list o un dict . Este crea una list eliminación pero elimina las claves en el dict original.

Otra opción:

 content = dict(k1='foo', k2='nope', k3='bar') selection = ['k1', 'k3'] filtered = filter(lambda i: i[0] in selection, content.items()) 

Pero obtienes una list (Python 2) o un iterador (Python 3) devuelto por filter() , no un dict .