J'ai la liste suivante:
[7, 9, 7, 15, None, 2, 0]
.. et je voulais une compréhension de liste qui renverra l'entier dans l'élément s'il y en a un même s'il vaut 0 et et qui renverra 1 pour un élément où les deux sous-éléments sont Aucun.
Je l'ai amené aussi loin que ceci:
[a or b if (a!=0 and b!=0) else 0 if set([a,b])=={0,None} else 1 if set([a,b])=={None} else -10 for a,b in z]
.. qui fonctionne presque , il renvoie:
z = [ [7,None], [9,None], [None,7], [None, 15], [None, None], [2,None], [0,None]]
Il n'a donc pas réussi à transformer l'élément [None, None] en 1. Quelqu'un sait-il comment le réparer ?
Le bit else -10 est juste là car je crois qu'une compréhension de liste écrite comme celle-ci doit se terminer par un else si vous l'oubliez lance une SyntaxError
3 Réponses :
Que diriez-vous de ceci?
[7, 9, 7, 15, 1, 2, 0]
Résultat:
[a if a is not None else b if b is not None else 1 for a, b in z]
Bien, comparé à pas Aucun ici ne le fait certainement lire plus comme l'anglais :-)
J'écrirais l'expression comme (appelant le premier élément a et le deuxième b):
[(1 if b is None else b) if a is None else a for a, b in z]
Cela lit immédiatement assez à l'envers, mais c'est ainsi que fonctionne l'expression ternaire. La compréhension de la liste est donc
(1 if b is None else b) if a is None else a
Vous pouvez également utiliser une genexp pour filtrer les éléments qui ne sont pas identiques à None et l'utiliser avec next et une valeur par défaut, par exemple:
[next((el for el in lst if el is not None), 1) for lst in z] # [7, 9, 7, 15, 1, 2, 0]
ne serait-il pas meilleur et plus lisible si vous utilisez des boucles for normales avec des conditions?
Vous avez raison de dire que l'expression conditionnelle
X if Y else Znécessite un composantelse, ou bien elle lève une SyntaxError. Ceci est vrai indépendamment du fait que l'expression soit dans une compréhension de liste. Mais si vous ne vous attendez jamais à ce que Z s'exécute en aucune circonstance, alors il n'y a pas grand chose à avoir une expression conditionnelle. Remplacez simplementX si Y sinon ZparX.Notez également qu'un
ifpeut apparaître dans une compréhension de liste sanselse, par exemple[i * 2 for i in range (10) if i> 5]. Mais ce n'est pas une expression conditionnelle, et elle ne peut pas venir avant lepour.Le simple vaut mieux que le complexe,Les cas spéciaux ne sont pas assez spéciaux. Penser le problème de manière organisée mène à la solution de @gmds: vérifiez d'aborda, puis vérifiezb, puis remplissez la valeur de l'espace réservé lorsque tout estAucun. Comme0ne doit pas être traité différemment des autres entiers, le code ne doit donc pas comparer les valeurs à0.