140 votes

Un moyen efficace de supprimer les clés contenant des chaînes vides d'un dict.

J'ai un dict et je voudrais supprimer toutes les clés pour lesquelles il y a des chaînes de valeurs vides.

metadata = {u'Composite:PreviewImage': u'(Binary data 101973 bytes)',
            u'EXIF:CFAPattern2': u''}

Quelle est la meilleure façon de procéder ?

235voto

BrenBarn Points 63718

Python 2.X

dict((k, v) for k, v in metadata.iteritems() if v)

Python 2.7 - 3.X

{k: v for k, v in metadata.items() if v}

Notez que toutes vos clés ont des valeurs. C'est juste que certaines de ces valeurs sont des chaînes vides. Il n'existe pas de clé sans valeur dans un dict ; si elle n'avait pas de valeur, elle ne serait pas dans le dict.

80voto

patriciasz Points 163

Il peut être encore plus court que La solution de BrenBarn (et plus lisible je pense)

{k: v for k, v in metadata.items() if v}

Testé avec Python 2.7.3.

22voto

nneonneo Points 56821

Si vous avez vraiment besoin de modifier le dictionnaire original :

empty_keys = [k for k,v in metadata.iteritems() if not v]
for k in empty_keys:
    del metadata[k]

Notez que nous devons faire une liste des clés vides car nous ne pouvons pas modifier un dictionnaire tout en l'itérant (comme vous l'avez peut-être remarqué). Cette opération est cependant moins coûteuse (en termes de mémoire) que la création d'un tout nouveau dictionnaire, sauf s'il y a beaucoup d'entrées avec des valeurs vides.

17voto

Marie Talcod Points 1

Si vous souhaitez une approche complète, mais succincte, de la gestion des structures de données du monde réel, qui sont souvent imbriquées et peuvent même contenir des cycles, je vous recommande de consulter le site suivant l'utilitaire remap du paquet utilitaire boltons .

Après pip install boltons ou la copie iterutils.py dans votre projet, faites-le :

from boltons.iterutils import remap

drop_falsey = lambda path, key, value: bool(value)
clean = remap(metadata, visit=drop_falsey)

Cette page contient beaucoup plus d'exemples, y compris ceux qui utilisent des objets beaucoup plus grands provenant de l'API de Github.

Il est purement Python, donc il fonctionne partout, et est entièrement testé dans Python 2.7 et 3.3+. Le meilleur de tous, c'est que je l'ai écrit exactement pour des cas comme celui-ci, donc si vous trouvez un cas qu'il ne gère pas, vous pouvez me contacter pour le corriger. ici même .

15voto

chachan Points 549

Sur la base de La solution de Ryan si vous avez également des listes et des dictionnaires imbriqués :

Pour Python 2 :

def remove_empty_from_dict(d):
    if type(d) is dict:
        return dict((k, remove_empty_from_dict(v)) for k, v in d.iteritems() if v and remove_empty_from_dict(v))
    elif type(d) is list:
        return [remove_empty_from_dict(v) for v in d if v and remove_empty_from_dict(v)]
    else:
        return d

Pour Python 3 :

def remove_empty_from_dict(d):
    if type(d) is dict:
        return dict((k, remove_empty_from_dict(v)) for k, v in d.items() if v and remove_empty_from_dict(v))
    elif type(d) is list:
        return [remove_empty_from_dict(v) for v in d if v and remove_empty_from_dict(v)]
    else:
        return d

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