J'ai un dictionnaire:
{'key1':1, 'key2':2, 'key3':3}
Je dois passer un sous-ensemble de ce dictionnaire au code tiers. Il ne veut qu'un dictionnaire contenant les clés ['key1', 'key2', 'key99']
et s'il obtient une autre clé (par exemple 'key3'
), il explose dans un désordre odieux. Le code en question étant hors de mon contrôle, je suis donc obligé de nettoyer mon dictionnaire.
Quel est le meilleur moyen de limiter un dictionnaire à un ensemble de clés?
Étant donné l'exemple de dictionnaire et les clés autorisées ci-dessus, je veux:
{'key1':1, 'key2':2}
In [38]: adict={'key1':1, 'key2':2, 'key3':3}
In [41]: dict((k,adict[k]) for k in ('key1','key2','key99') if k in adict)
Out[41]: {'key1': 1, 'key2': 2}
En Python3 (ou Python2.7 ou ultérieur), vous pouvez le faire avec un dict-comprehension too:
>>> {k:adict[k] for k in ('key1','key2','key99') if k in adict}
{'key2': 2, 'key1': 1}
dict(filter(lambda i:i[0] in validkeys, d.iteritems()))
En Python moderne (2.7 +, 3.0 +), utilisez un dictionnaire comprenant:
d = {'key1':1, 'key2':2, 'key3':3}
included_keys = ['key1', 'key2', 'key99']
{k:v for k,v in d.items() if k in included_keys}
Une autre solution sans si dans la compréhension de dict.
>>> a = {'key1':1, 'key2':2, 'key3':3}
>>> b = {'key1':1, 'key2':2}
>>> { k:a[k] for k in b.keys()}
{'key2': 2, 'key1': 1}
Ma façon de faire est.
from operator import itemgetter
def subdict(d, ks):
return dict(Zip(ks, itemgetter(*ks)(d)))
my_dict = {'key1':1, 'key2':2, 'key3':3}
subdict(my_dict, ['key1', 'key3'])
Mettre à jour
Je dois admettre que l'implémentation ci-dessus ne gère pas le cas lorsque la longueur de ks
est 0 ou 1. Le code suivant gère la situation et il ne s'agit plus d'une ligne.
def subdict(d, ks):
vals = []
if len(ks) >= 1:
vals = itemgetter(*ks)(d)
if len(ks) == 1:
vals = [vals]
return dict(Zip(ks, vals))
Avec une classe complexe Myclass
étant une sous-classe de collections.UserDict
. Pour en sélectionner un sous-ensemble, c’est-à-dire conserver toutes ses propriétés de conteneur, il est pratique de définir une méthode, par ex. nommé sub
comme suit:
def sub(self, keys):
subset = Myclass() # no arguments; works if defined with only keyword arguments
for key in keys:
subset[key] = self[key]
return subset
Il est ensuite utilisé comme Myclass.sub([key1, key2 ...]
)