Question si / sinon dans la compréhension de la liste de Python?


Comment puis-je faire ce qui suit en Python?

row = [unicode(x.strip()) for x in row if x is not None else '']

Essentiellement:

  1. remplacer tous les Nones par des chaînes vides, puis
  2. effectuer une fonction.

536
2017-11-23 19:56


origine


Réponses:


Vous pouvez totalement faire cela, c'est juste un problème de commande:

[ unicode(x.strip()) if x is not None else '' for x in row ]

Notez que cela utilise en fait une structure de langage différente, expression conditionnelle, qui ne fait pas partie de la syntaxe de compréhension, tandis que le if après le for…in fait partie de la compréhension de la liste et utilisé pour filtre éléments de la source itérable.

Les expressions conditionnelles peuvent être utilisées dans toutes sortes de situations où vous voulez choisir entre deux valeurs d'expression basées sur certaines conditions. Cela fait la même chose que le opérateur ternaire ?: qui existe dans d'autres langues. Par exemple:

value = 123
print(value, 'is', 'even' if value % 2 == 0 else 'odd')

824
2017-11-23 19:59



Une manière:

def change(f):
    if f is None:
        return unicode(f.strip())
    else:
        return ''

row = [change(x) for x in row]

Bien que vous ayez:

row = map(change, row)

Ou vous pouvez utiliser un lambda en ligne.


34
2017-11-23 20:00



Voici un autre exemple illustratif:

>>> print(", ".join(["ha" if i else "Ha" for i in range(3)]) + "!")
Ha, ha, ha!

Il exploite le fait que if i évalue à False pour 0 et à True pour toutes les autres valeurs générées par la fonction range(). Par conséquent, la compréhension de la liste est évaluée comme suit:

>>> ["ha" if i else "Ha" for i in range(3)]
['Ha', 'ha', 'ha']

30
2017-10-07 21:37



Le problème spécifique a déjà été résolu dans les réponses précédentes, donc je vais aborder l'idée générale de l'utilisation des conditionnels à l'intérieur des listes de compréhension.

Voici un exemple qui montre comment les conditions peuvent être écrites dans une compréhension de liste:

X = [1.5, 2.3, 4.4, 5.4, 'n', 1.5, 5.1, 'a']     # Original list

# Extract non-strings from X to new list
X_non_str = [el for el in X if not isinstance(el, str)]  # When using only 'if', put 'for' in the beginning

# Change all strings in X to 'b', preserve everything else as is
X_str_changed = ['b' if isinstance(el, str) else el for el in X]  # When using 'if' and 'else', put 'for' in the end

Notez que dans la première compréhension de liste pour X_non_str, la commande est:

valeur  pour  expression1  si  expression2

et dans la dernière compréhension de la liste pour X_str_changed, la commande est:

valeur1  si  expression1  autre  valeur2  pour  expression2

J'ai toujours du mal à me souvenir que valeur1 doit être avant si et valeur2 doit être après autre. Ma tête veut que les deux soient avant ou après.

Je suppose qu'il est conçu comme ça parce qu'il ressemble à un langage normal, par ex. "Je veux rester à l'intérieur si il pleut, autre Je veux sortir "


3
2018-06-21 11:28



Les autres solutions sont bonnes pour un seul if / else construction. Cependant, les déclarations ternaires dans les listes de compréhension sont sans doute difficiles à lire.

L'utilisation d'une fonction facilite la lisibilité, mais une telle solution est difficile à étendre ou à adapter dans un flux de travail où le mappage est une entrée. Un dictionnaire peut atténuer ces préoccupations:

row = [None, 'This', 'is', 'a', 'filler', 'test', 'string', None]

d = {None: '', 'filler': 'manipulated'}

res = [d.get(x, x) for x in row]

print(res)

['', 'This', 'is', 'a', 'manipulated', 'test', 'string', '']

0
2017-07-14 10:24