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 ?

2voto

SmokeRaven Points 101

J'ai lu toutes les réponses dans ce fil et certaines se réfèrent également à ce fil : Suppression des dicts vides dans un dictionnaire imbriqué avec une fonction récursive

J'ai d'abord utilisé cette solution ici et elle a très bien fonctionné :

Tentative 1 : Trop chaud (pas performant ou à l'épreuve du temps) :

def scrub_dict(d):
    if type(d) is dict:
        return dict((k, scrub_dict(v)) for k, v in d.iteritems() if v and scrub_dict(v))
    else:
        return d

Mais certains problèmes de performance et de compatibilité ont été soulevés dans le monde de Python 2.7 :

  1. utiliser isinstance au lieu de type
  2. dérouler la liste comp en for boucle pour l'efficacité
  3. utiliser python3 en toute sécurité items au lieu de iteritems

Tentative 2 : Trop froid (manque de mémorisation) :

def scrub_dict(d):
    new_dict = {}
    for k, v in d.items():
        if isinstance(v,dict):
            v = scrub_dict(v)
        if not v in (u'', None, {}):
            new_dict[k] = v
    return new_dict

DOH ! Ce n'est pas récursif et pas du tout mémoïsant.

Tentative 3 : Juste ce qu'il faut (jusqu'à présent) :

def scrub_dict(d):
    new_dict = {}
    for k, v in d.items():
        if isinstance(v,dict):
            v = scrub_dict(v)
        if not v in (u'', None, {}):
            new_dict[k] = v
    return new_dict

2voto

Mat Points 51

Pour conserver les valeurs 0 et Faux mais se débarrasser des valeurs vides, vous pouvez utiliser :

{k: v for k, v in metadata.items() if v or v == 0 or v is False}

Pour un dict imbriqué avec des types de valeurs mixtes, vous pouvez utiliser :

def remove_empty_from_dict(d):
  if isinstance(d, dict):
    return dict((k, remove_empty_from_dict(v)) for k, v in d.items() \
            if v or v == 0 or v is False and remove_empty_from_dict(v) is not None)
  elif isinstance(d, list):
    return [remove_empty_from_dict(v) for v in d 
            if v or v == 0 or v is False and remove_empty_from_dict(v) is not None]
  else:
    if d or d == 0 or d is False:
      return d

1voto

Marcello de Sales Points 1771

Dicts mélangés avec Arrays

  • La réponse à Tentative 3 : Juste ce qu'il faut (jusqu'à présent) de La réponse de BlissRage ne gère pas correctement les éléments des tableaux. J'inclus un patch au cas où quelqu'un en aurait besoin. La méthode gère les tableaux avec le bloc d'instructions de if isinstance(v, list): qui nettoie la liste en utilisant l'original scrub_dict(d) mise en œuvre.

    @staticmethod
    def scrub_dict(d):
        new_dict = {}
        for k, v in d.items():
            if isinstance(v, dict):
                v = scrub_dict(v)
            if isinstance(v, list):
                v = scrub_list(v)
            if not v in (u'', None, {}, []):
                new_dict[k] = v
        return new_dict
    
    @staticmethod
    def scrub_list(d):
        scrubbed_list = []
        for i in d:
            if isinstance(i, dict):
                i = scrub_dict(i)
            scrubbed_list.append(i)
        return scrubbed_list

1voto

KokoEfraim Points 108

"Comme j'écris aussi actuellement une application de bureau pour mon travail avec Python, j'ai trouvé dans une application de saisie de données quand il y a beaucoup d'entrées et que certaines ne sont pas obligatoires donc l'utilisateur peut les laisser vides, pour la validation, il est facile de saisir toutes les entrées et ensuite de rejeter les clés ou valeurs vides d'un dictionnaire. Donc mon code ci-dessus montre comment nous pouvons facilement les enlever, en utilisant la compréhension du dictionnaire et garder l'élément de valeur du dictionnaire qui n'est pas vide. J'utilise Python 3.8.3.

data = {'':'', '20':'', '50':'', '100':'1.1', '200':'1.2'}

dic = {key:value for key,value in data.items() if value != ''}

print(dic)

{'100': '1.1', '200': '1.2'}

0voto

Serguei Fedorov Points 2001

Une autre façon de procéder consiste à utiliser la compréhension du dictionnaire. Cela devrait être compatible avec 2.7+

result = {
    key: value for key, value in
    {"foo": "bar", "lorem": None}.items()
    if value
}

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