Diccionario de Python: obtener la lista de valores para la lista de claves

¿Existe una forma integrada / rápida de usar una lista de claves de un diccionario para obtener una lista de los elementos correspondientes?

Por ejemplo tengo:

>>> mydict = {'one': 1, 'two': 2, 'three': 3} >>> mykeys = ['three', 'one'] 

¿Cómo puedo usar mykeys para obtener los valores correspondientes en el diccionario como una lista?

 >>> mydict.WHAT_GOES_HERE(mykeys) [3, 1] 

Una lista de comprensión parece ser una buena manera de hacer esto:

 >>> [mydict[x] for x in mykeys] [3, 1] 

Un par de formas diferentes de list-comp:

  • Crear lista y lanzar una excepción si no se encuentra la clave: map(mydict.__getitem__, mykeys)
  • Crear lista con None si no se encuentra la clave: map(mydict.get, mykeys)

Alternativamente, el uso de operator.itemgetter puede devolver una tupla:

 from operator import itemgetter myvalues = itemgetter(*mykeys)(mydict) # use `list(...)` if list is required 

Nota : en Python3, el map devuelve un iterador en lugar de una lista. Utilice la list(map(...)) para una lista.

Una pequeña comparación de velocidad:

 Python 2.7.11 |Anaconda 2.4.1 (64-bit)| (default, Dec 7 2015, 14:10:42) [MSC v.1500 64 bit (AMD64)] on win32 In[1]: l = [0,1,2,3,2,3,1,2,0] In[2]: m = {0:10, 1:11, 2:12, 3:13} In[3]: %timeit [m[_] for _ in l] # list comprehension 1000000 loops, best of 3: 762 ns per loop In[4]: %timeit map(lambda _: m[_], l) # using 'map' 1000000 loops, best of 3: 1.66 µs per loop In[5]: %timeit list(m[_] for _ in l) # a generator expression passed to a list constructor. 1000000 loops, best of 3: 1.65 µs per loop In[6]: %timeit map(m.__getitem__, l) The slowest run took 4.01 times longer than the fastest. This could mean that an intermediate result is being cached 1000000 loops, best of 3: 853 ns per loop In[7]: %timeit map(m.get, l) 1000000 loops, best of 3: 908 ns per loop In[33]: from operator import itemgetter In[34]: %timeit list(itemgetter(*l)(m)) The slowest run took 9.26 times longer than the fastest. This could mean that an intermediate result is being cached 1000000 loops, best of 3: 739 ns per loop 

Así que la comprensión de lista y el guardameta son las formas más rápidas de hacer esto.

ACTUALIZACIÓN: para grandes listas aleatorias y mapas tuve resultados un poco diferentes:

 Python 2.7.11 |Anaconda 2.4.1 (64-bit)| (default, Dec 7 2015, 14:10:42) [MSC v.1500 64 bit (AMD64)] on win32 In[2]: import numpy.random as nprnd l = nprnd.randint(1000, size=10000) m = dict([(_, nprnd.rand()) for _ in range(1000)]) from operator import itemgetter import operator f = operator.itemgetter(*l) %timeit f(m) %timeit list(itemgetter(*l)(m)) %timeit [m[_] for _ in l] # list comprehension %timeit map(m.__getitem__, l) %timeit list(m[_] for _ in l) # a generator expression passed to a list constructor. %timeit map(m.get, l) %timeit map(lambda _: m[_], l) 1000 loops, best of 3: 1.14 ms per loop 1000 loops, best of 3: 1.68 ms per loop 100 loops, best of 3: 2 ms per loop 100 loops, best of 3: 2.05 ms per loop 100 loops, best of 3: 2.19 ms per loop 100 loops, best of 3: 2.53 ms per loop 100 loops, best of 3: 2.9 ms per loop 

Entonces, en este caso, el ganador claro es f = operator.itemgetter(*l); f(m) f = operator.itemgetter(*l); f(m) y claro externo: map(lambda _: m[_], l) .

ACTUALIZACIÓN para Python 3.6.4:

 import numpy.random as nprnd l = nprnd.randint(1000, size=10000) m = dict([(_, nprnd.rand()) for _ in range(1000)]) from operator import itemgetter import operator f = operator.itemgetter(*l) %timeit f(m) %timeit list(itemgetter(*l)(m)) %timeit [m[_] for _ in l] # list comprehension %timeit list(map(m.__getitem__, l)) %timeit list(m[_] for _ in l) # a generator expression passed to a list constructor. %timeit list(map(m.get, l)) %timeit list(map(lambda _: m[_], l) 1.66 ms ± 74.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each) 2.1 ms ± 93.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 2.58 ms ± 88.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 2.36 ms ± 60.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 2.98 ms ± 142 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 2.7 ms ± 284 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 3.14 ms ± 62.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) 

Por lo tanto, los resultados para Python 3.6.4 son casi los mismos.

Prueba esto:

 mydict = {'one': 1, 'two': 2, 'three': 3} mykeys = ['three', 'one','ten'] newList=[mydict[k] for k in mykeys if k in mydict] print newList [3, 1] 

Aquí hay tres formas.

Levantar KeyError cuando no se encuentra la clave:

 result = [mapping[k] for k in iterable] 

Valores predeterminados para las claves faltantes.

 result = [mapping.get(k, default_value) for k in iterable] 

Saltando las llaves faltantes.

 result = [mapping[k] for k in iterable if k in mapping] 

Prueba esto:

 mydict = {'one': 1, 'two': 2, 'three': 3} mykeys = ['three', 'one'] # if there are many keys, use a set [mydict[k] for k in mykeys] => [3, 1] 

Las pandas hacen esto muy elegantemente, aunque las comprensiones de la lista ofc siempre serán más técnicamente Pythonic. No tengo tiempo para hacer una comparación de velocidad en este momento (volveré más tarde y la pondré en):

 import pandas as pd mydict = {'one': 1, 'two': 2, 'three': 3} mykeys = ['three', 'one'] temp_df = pd.DataFrame().append(mydict) # You can export DataFrames to a number of formats, using a list here. temp_df[mykeys].values[0] # Returns: array([ 3., 1.]) # If you want a dict then use this instead: # temp_df[mykeys].to_dict(orient='records')[0] # Returns: {'one': 1.0, 'three': 3.0} 
 new_dict = {x: v for x, v in mydict.items() if x in mykeys} 

O simplemente mydict.keys() Es un método integrado para los diccionarios. También explore mydict.values() y mydict.items() .

// Ah, el post de OP me confundió.

Tras el cierre de Python: forma eficiente de crear una lista a partir de valores de dict con un orden determinado

Recuperando las claves sin construir la lista:

 from __future__ import (absolute_import, division, print_function, unicode_literals) import collections class DictListProxy(collections.Sequence): def __init__(self, klist, kdict, *args, **kwargs): super(DictListProxy, self).__init__(*args, **kwargs) self.klist = klist self.kdict = kdict def __len__(self): return len(self.klist) def __getitem__(self, key): return self.kdict[self.klist[key]] myDict = {'age': 'value1', 'size': 'value2', 'weigth': 'value3'} order_list = ['age', 'weigth', 'size'] dlp = DictListProxy(order_list, myDict) print(','.join(dlp)) print() print(dlp[1]) 

La salida:

 value1,value3,value2 value3 

Que coincide con el orden dado por la lista

 reduce(lambda x,y: mydict.get(y) and x.append(mydict[y]) or x, mykeys,[]) 

En caso de que haya llaves no en dict.