1
votes

Quel est le moyen efficace de supprimer les valeurs vides de la liste interne de dict?

Quel est le moyen efficace de supprimer les valeurs vides du dictionnaire qui est enregistré dans la liste.

[{'l1k1': 'l1v1', 'l1k2': 'l1v2'}, {'l2k1': 'l2v1'}]

Sortie réelle:

[{'l1k1': 'l1v1', 'l1k2': 'l1v2'}, {'l2k1': 'l2v1', 'l2k2': ''}]

Production attendue:

list1 = [{'l1k1': 'l1v1', 'l1k2': 'l1v2'}, {'l2k1': 'l2v1', 'l2k2': ''}]
list2 = []
for l in list1:
  d = {}
  for k, v in l.items():
    if v.strip() is not None or v.strip() != '':
      d[k] = v
  list2.append(d)
print(list2)


2 commentaires

pointilleux, mais dans votre exemple, vous ne supprimez pas les paires clé / valeur, vous ne les copiez tout simplement pas


Supposons que v est une chaîne vide. Dans ce cas (v.strip () n'est pas None) sera True, donc la chaîne vide est quand même ajoutée au dict d en raison de la condition 'or'. Raisonner sur la combinaison de négatifs (n'est pas et! =) Est difficile et je recommanderais de l'éviter.


5 Réponses :


7
votes

Essaye ça:

list2
=> [{'l1k1': 'l1v1', 'l1k2': 'l1v2'}, {'l2k1': 'l2v1'}]

Notez que la vérification correcte à faire ici est v and v.strip() , qui garantit que la chaîne n'est pas None et ne v and v.strip() pas tous les espaces. Cela fonctionne comme prévu:

list1 = [{'l1k1': 'l1v1', 'l1k2': 'l1v2'}, {'l2k1': 'l2v1', 'l2k2': ''}]
list2 = [{ k: v for k, v in d.items() if v and v.strip() } for d in list1]

Il est efficace car il utilise des compréhensions de listes et des compréhensions de dictionnaires, qui sont plus rapides que de faire des boucles explicites. De plus, c'est assez compact et idiomatique :)


3 commentaires

Je ne sais pas, j'obtiens le même résultat, list1 = [{'l1k1': 'l1v1', 'l1k2': 'l1v2'}, {'l2k1': 'l2v1', 'l2k2': ''}] list2 = [{k: v pour k, v dans d.items ()} pour d dans list1] print (list2) print (list1)


Parfois, j'obtiens cette erreur: AttributeError: l'objet 'dict' n'a pas d'attribut 'strip'


@Pallaveera cela signifie que certains de vos dictats ont des valeurs qui sont eux-mêmes des dictons! Vérifiez vos données d'entrée, elles ne ressemblent pas à celles de la question.



7
votes

Essaye ça :

list2 = [{k:v for k,v in i.items() if v} for i in list1]

Nous pouvons utiliser simultanément la compréhension de dict et la compréhension de liste. Nous bouclons pour chaque élément (qui est un dictionnaire) de list1 , et prenons simplement ces paires clé-valeur où la valeur ou value.strip() pour la clé correspondante dans le dictionnaire n'est pas une chaîne vide.

Une version plus courte pour annuler les valeurs avec le type None également:

list2 = [{k:v for k,v in i.items() if v!= '' or v.strip() != ''} for i in list1]


3 commentaires

c'est bien mais vous devriez probablement expliquer un peu ce que cela fait, les compréhensions ne sont pas les choses les plus évidentes pour les nouveaux arrivants


C'est trop verbeux (sans parler d'erreur, à cause du or ), et cela ne gère pas non plus le cas None . Vérifiez ma réponse pour une solution plus simple.


La partie strip() de ce code est inutile, car vous utilisez or . Si v=' ' alors v!='' or v.strip()!='' Est vrai.



0
votes

Voici une alternative simple, n'utilisant pas la compréhension de liste qui peut être plus facile à suivre pour vous:

for d in list1:
  for k in d.keys():
      if d[k] != '':
          list2.append({k:d[k]})


0 commentaires

0
votes

faire une copie de votre liste n'est pas très efficace, sauf si vous VOULEZ également conserver l'original. vous pouvez simplement supprimer les entrées qui sont "vides" comme ceci:

list1 = [{'l1k1': 'l1v1', 'l1k2': 'l1v2'}, {'l2k1': 'l2v1', 'l2k2': ''}]
for item in list1:
    for key in list(item.keys()):
        if not item[key].strip():
            del item[key]

cette list(item.keys()) est importante. pourquoi lister? parce que python n'aime pas quand vous changez la taille du dict pendant l'itération, si nous pré-récupérons les clés, nous itérerons sur une liste au lieu d'un générateur.

not item[key].strip() est également un bon à noter, les chaînes vides évaluent à False tandis que les chaînes non vides évaluent à True

* note: à proprement parler, le .keys() n'est pas nécessaire, mais il aide à la lisibilité si vous êtes nouveau sur python


0 commentaires

0
votes
list2 = [{k: v for k,v in dic.items() if v} for dic in list1]

0 commentaires