Existe-t-il un moyen intégré / rapide d'utiliser une liste de clés d'un dictionnaire pour obtenir une liste des éléments correspondants?
Par exemple j'ai:
>>> mydict = {'one': 1, 'two': 2, 'three': 3}
>>> mykeys = ['three', 'one']
Comment puis-je utiliser mykeys
pour obtenir les valeurs correspondantes dans le dictionnaire sous forme de liste?
>>> mydict.WHAT_GOES_HERE(mykeys)
[3, 1]
python
list
dictionary
key
FazJaxton
la source
la source
mydict
s'agit d'un appel de fonction (qui renvoie un dict), cela appelle la fonction plusieurs fois, non?Quelques autres moyens que list-comp:
map(mydict.__getitem__, mykeys)
None
si la clé est introuvable:map(mydict.get, mykeys)
Alternativement, using
operator.itemgetter
peut retourner un tuple:from operator import itemgetter myvalues = itemgetter(*mykeys)(mydict) # use `list(...)` if list is required
Remarque : en Python3,
map
renvoie un itérateur plutôt qu'une liste. Utilisezlist(map(...))
pour une liste.la source
Une petite comparaison de vitesse:
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
La compréhension de liste et le sélecteur d'objets sont donc les moyens les plus rapides de le faire.
MISE À JOUR: Pour les grandes listes aléatoires et les cartes, j'ai eu des résultats un peu différents:
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
Donc , dans ce cas , le gagnant est
f = operator.itemgetter(*l); f(m)
et extérieur clair:map(lambda _: m[_], l)
.MISE À JOUR pour 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)
Ainsi, les résultats pour Python 3.6.4 sont presque les mêmes.
la source
Voici trois façons.
Relever
KeyError
lorsque la clé n'est pas trouvée:result = [mapping[k] for k in iterable]
Valeurs par défaut des clés manquantes.
result = [mapping.get(k, default_value) for k in iterable]
Ignorer les clés manquantes.
result = [mapping[k] for k in iterable if k in mapping]
la source
found_keys = mapping.keys() & iterable
donneTypeError: unsupported operand type(s) for &: 'list' and 'list'
sur python 2.7; `found_keys = [key for key in mapping.keys () if key in iterable] fonctionne mieuxEssaye ça:
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]
la source
Essaye ça:
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]
la source
items()
est préférable, il n'est pas nécessaire d'effectuer une recherche supplémentaire, il n'y a pas d'len(mydict)*len(mykeys)
opération ici! (notez que j'utilise un ensemble)mykeys
est amortie en temps constant, j'utilise un ensemble, pas une listenew_dict = {x: v for x, v in mydict.items() if x in mykeys}
la source
Les pandas le font très élégamment, bien que la compréhension des listes soit toujours plus techniquement pythonique. Je n'ai pas le temps de faire une comparaison de vitesse pour le moment (je reviendrai plus tard et je la placerai):
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}
la source
Ou simplement
mydict.keys()
c'est un appel de méthode intégré pour les dictionnaires. Explorez égalementmydict.values()
etmydict.items()
.// Ah, le poste OP m'a confondu.
la source
Après la fermeture de Python: moyen efficace de créer une liste à partir de valeurs dict avec un ordre donné
Récupérer les clés sans construire la liste:
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])
Le résultat:
Qui correspond à l'ordre donné par la liste
la source
reduce(lambda x,y: mydict.get(y) and x.append(mydict[y]) or x, mykeys,[])
au cas où il n'y aurait pas de clés dans dict.
la source