91 votes

Obtenir un sous-ensemble d'un dictionnaire Python

J'ai un dictionnaire :

{'key1':1, 'key2':2, 'key3':3}

J'ai besoin de passer un sous-ensemble de ce dictionnaire à un code tiers. Il veut seulement un dictionnaire contenant des clés ['key1', 'key2', 'key99'] et s'il obtient une autre clé (par exemple 'key3' ), il explose dans un méchant désordre. Le code en question est hors de mon contrôle et je me retrouve dans une situation où je dois nettoyer mon dictionnaire.

Quelle est la meilleure façon 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}

91voto

unutbu Points 222216
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 une balise dict-compréhension aussi :

>>> {k:adict[k] for k in ('key1','key2','key99') if k in adict}
{'key2': 2, 'key1': 1}

9 votes

Les compréhensions de dictées sont également présentes dans Python 2.7.

0 votes

J'aimerais qu'il y ait un opérateur pour ça. Comme adict - {'key1'} == {'key2':2, 'key3':3}

0 votes

Il ne semble pas y avoir d'inverse sensible de la dict.update méthode

26voto

Björn Pollex Points 41424
dict(filter(lambda i:i[0] in validkeys, d.iteritems()))

5 votes

Pour python 3, cela devrait être d.items() .

12voto

watsonic Points 1129

Dans les versions modernes de Python (2.7+,3.0+), utilisez un dictionnaire de compréhension :

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}

0 votes

Si je comprends bien, cela serait moins efficace dans le cas où len(d) >> len(included_keys) ( >> dénote "beaucoup plus grand"). Mais je suppose que dans le cas courant, len(d) n'est pas très grand...

0 votes

Merci de partager. C'est la seule solution qui a fonctionné pour moi. Aucune des solutions ci-dessus n'a fonctionné.

11voto

Nazime Lakehal Points 76

Une autre solution sans si en dict compréhension.

>>> a = {'key1':1, 'key2':2, 'key3':3}
>>> b = {'key1':1, 'key2':2}
>>> { k:a[k] for k in b.keys()}
{'key2': 2, 'key1': 1}

4voto

Lei Zhao Points 86

Ma façon de procéder est la suivante .

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'])

Mise à jour

Je dois cependant admettre que l'implémentation ci-dessus ne gère pas le cas où la longueur de la variable ks est 0 ou 1. Le code suivant gère la situation et ce n'est plus un one-liner.

def subdict(d, ks):
    vals = []
    if len(ks) >= 1:
        vals = itemgetter(*ks)(d)
        if len(ks) == 1:
            vals = [vals]
    return dict(zip(ks, vals))

0 votes

Je vais souvent from operator import itemgetter as ig pour économiser un peu d'espace de ligne horizontale et de frappe. Je ne pense pas m'être souvenu que itemgetter prendrait plusieurs éléments à récupérer. Bon rappel, merci !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X