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)
5 Réponses :
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 :)
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.
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]
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.
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]})
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
list2 = [{k: v for k,v in dic.items() if v} for dic in list1]
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.