valor resueltos recorrer lista elementos ejercicios diccionarios diccionario dentro buscar anidados agregar python dictionary associative-array

resueltos - lista de diccionarios python



¿Extraer subconjunto de pares clave-valor del objeto del diccionario de Python? (9)

Tengo un objeto de diccionario grande que tiene varios pares de valores clave (aproximadamente 16), pero solo estoy interesado en 3 de ellos. ¿Cuál es la mejor manera (más corta / eficiente / más elegante) para lograrlo?

Lo mejor que sé es:

bigdict = {''a'':1,''b'':2,....,''z'':26} subdict = {''l'':bigdict[''l''], ''m'':bigdict[''m''], ''n'':bigdict[''n'']}

Estoy seguro de que hay una manera más elegante que esta. Ideas?


Bueno, esto es algo que me ha molestado varias veces, así que gracias Jayesh por preguntármelo.

Las respuestas anteriores parecen ser una solución tan buena como cualquier otra, pero si está usando todo este código, tiene sentido envolver la funcionalidad en mi humilde opinión. Además, hay dos posibles casos de uso aquí: uno en el que le importa si todas las palabras clave están en el diccionario original. y uno donde no lo haces. Sería bueno tratar a ambos por igual.

Así que, para mi valor de dos peniques, sugiero escribir una subclase de diccionario, por ejemplo

class my_dict(dict): def subdict(self, keywords, fragile=False): d = {} for k in keywords: try: d[k] = self[k] except KeyError: if fragile: raise return d

Ahora puedes sacar un sub-diccionario con

orig_dict.subdict(keywords)

Ejemplos de uso:

# ## our keywords are letters of the alphabet keywords = ''abcdefghijklmnopqrstuvwxyz'' # ## our dictionary maps letters to their index d = my_dict([(k,i) for i,k in enumerate(keywords)]) print(''Original dictionary:/n%r/n/n'' % (d,)) # ## constructing a sub-dictionary with good keywords oddkeywords = keywords[::2] subd = d.subdict(oddkeywords) print(''Dictionary from odd numbered keys:/n%r/n/n'' % (subd,)) # ## constructing a sub-dictionary with mixture of good and bad keywords somebadkeywords = keywords[1::2] + ''A'' try: subd2 = d.subdict(somebadkeywords) print("We shouldn''t see this message") except KeyError: print("subd2 construction fails:") print("/toriginal dictionary doesn''t contain some keys/n/n") # ## Trying again with fragile set to false try: subd3 = d.subdict(somebadkeywords, fragile=False) print(''Dictionary constructed using some bad keys:/n%r/n/n'' % (subd3,)) except KeyError: print("We shouldn''t see this message")

Si ejecuta todo el código anterior, debería ver (algo así como) la siguiente salida (perdón por el formato):

Diccionario original:
{''a'': 0, ''c'': 2, ''b'': 1, ''e'': 4, ''d'': 3, ''g'': 6, ''f'': 5, ''i'': 8, '' h '': 7,'' k '': 10,'' j '': 9,'' m '': 12,'' l '': 11,'' o '': 14,'' n '': 13,'' q '': 16,'' p '' : 15, ''s'': 18, ''r'': 17, ''u'': 20, ''t'': 19, ''w'': 22, ''v'': 21, ''y'': 24, ''x'': 23 , ''z'': 25}

Diccionario de teclas de números impares:
{''a'': 0, ''c'': 2, ''e'': 4, ''g'': 6, ''i'': 8, ''k'': 10, ''m'': 12, ''o'': 14, '' q '': 16,'' s '': 18,'' u '': 20,'' w '': 22,'' y '': 24}

construcción subd2 falla:
diccionario original no contiene algunas claves

Diccionario construido usando algunas teclas malas:
{''b'': 1, ''d'': 3, ''f'': 5, ''h'': 7, ''j'': 9, ''l'': 11, ''n'': 13, ''p'': 15, '' r '': 17,'' t '': 19,'' v '': 21,'' x '': 23,'' z '': 25}


Esta respuesta utiliza una comprensión del diccionario similar a la respuesta seleccionada, pero no lo hará excepto en un elemento faltante.

Versión de Python 2:

{k:v for k, v in bigDict.iteritems() if k in (''l'', ''m'', ''n'')}

Versión de Python 3:

{k:v for k, v in bigDict.items() if k in (''l'', ''m'', ''n'')}


Otra más (prefiero la respuesta de Mark Longair)

di = {''a'':1,''b'':2,''c'':3} req = [''a'',''c'',''w''] dict([i for i in di.iteritems() if i[0] in di and i[0] in req])


Tal vez:

subdict=dict([(x,bigdict[x]) for x in [''l'', ''m'', ''n'']])

Python 3 incluso admite lo siguiente:

subdict={a:bigdict[a] for a in [''l'',''m'',''n'']}

Tenga en cuenta que puede verificar la existencia en el diccionario de la siguiente manera:

subdict=dict([(x,bigdict[x]) for x in [''l'', ''m'', ''n''] if x in bigdict])

resp. para python 3

subdict={a:bigdict[a] for a in [''l'',''m'',''n''] if a in bigdict}


También puedes usar el mapa (que es una función muy útil para conocer de todos modos):

sd = dict(map(lambda k: (k, l.get(k, None)), l))

Ejemplo:

large_dictionary = {''a1'':123, ''a2'':45, ''a3'':344} list_of_keys = [''a1'', ''a3''] small_dictionary = dict(map(lambda key: (key, large_dictionary.get(key, None)), list_of_keys))

PD. Tomé prestado el .get (clave, Ninguno) de una respuesta anterior :)


Tu podrías intentar:

dict((k, bigdict[k]) for k in (''l'', ''m'', ''n''))

... o en Python 3 Versiones de Python 2.7 o posteriores (gracias a Fábio Diniz por señalar que también funciona en 2.7) :

{k: bigdict[k] for k in (''l'', ''m'', ''n'')}

Actualización: como señala Håvard S , supongo que usted sabe que las claves estarán en el diccionario; vea su respuesta si no puede hacer esa suposición. Alternativamente, como lo señala el timbo en los comentarios, si desea que una clave que falta en bigdict a None , puede hacerlo:

{k: bigdict.get(k, None) for k in (''l'', ''m'', ''n'')}

Si está usando Python 3, y solo quiere que las claves en el nuevo dict que existen en la original, puede usar el hecho de que los objetos de vista implementan algunas operaciones de configuración:

{k: bigdict[k] for k in bigdict.keys() & {''l'', ''m'', ''n''}}


Un poco de comparación de velocidad para todos los métodos mencionados:

Python 2.7.11 |Anaconda 2.4.1 (64-bit)| (default, Jan 29 2016, 14:26:21) [MSC v.1500 64 bit (AMD64)] on win32 In[2]: import numpy.random as nprnd keys = nprnd.randint(1000, size=10000) bigdict = dict([(_, nprnd.rand()) for _ in range(1000)]) %timeit {key:bigdict[key] for key in keys} %timeit dict((key, bigdict[key]) for key in keys) %timeit dict(map(lambda k: (k, bigdict[k]), keys)) %timeit dict(filter(lambda i:i[0] in keys, bigdict.items())) %timeit {key:value for key, value in bigdict.items() if key in keys} 100 loops, best of 3: 3.09 ms per loop 100 loops, best of 3: 3.72 ms per loop 100 loops, best of 3: 6.63 ms per loop 10 loops, best of 3: 20.3 ms per loop 100 loops, best of 3: 20.6 ms per loop

Como era de esperar: las comprensiones de diccionarios son la mejor opción.


Un poco más corto, al menos:

wanted_keys = [''l'', ''m'', ''n''] # The keys you want dict((k, bigdict[k]) for k in wanted_keys if k in bigdict)


interesting_keys = (''l'', ''m'', ''n'') subdict = {x: bigdict[x] for x in interesting_keys if x in bigdict}