si / sinon dans la compréhension de 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 avec des cordes vides, puis
  2. effectuer une fonction.
563
demandé sur the Tin Man 2010-11-23 22:56:44

5 réponses

Vous pouvez tout à fait faire ça, c'est juste une commande de question:

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

notez que cela utilise en fait une construction de langue différente, une expression conditionnelle , qui elle-même 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 liste et utilisé à filtre éléments de la source iterable.

Les expressions conditionnelles peuvent être utilisées dans toutes sortes de situations où vous voulez choisir entre deux valeurs d'expression basées sur une condition. 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')
867
répondu poke 2017-04-04 16:38:22

:

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

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

bien que vous ayez alors:

row = map(change, row)

ou vous pouvez utiliser un lambda inline.

37
répondu Adam Vandenberg 2010-11-23 20:00:19

voici un autre exemple:

>>> 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']
31
répondu Bengt 2013-06-14 17:09:16

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 d'utiliser des conditions à l'intérieur des compréhensions de liste.

voici un exemple qui montre comment les conditions peuvent être écrites à l'intérieur d'une liste de compréhension:

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

noter que dans la première liste de compréhension pour X_non_str , l'ordre est:

valeur pour expression1 si expression2

et dans la dernière liste compréhension pour X_str_changed , l'ordre est:

valeur1 si expression1 else valeur2 pour expression2

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

je suppose qu'il est conçu comme cela parce qu'il ressemble au langage normal, par exemple "je veux rester à l'intérieur si il pleut, else je veux aller à l'extérieur"

7
répondu Tim Skov Jacobsen 2018-06-21 13:59:27

les autres solutions sont idéales pour une construction unique if / else . Toutefois, les déclarations ternaires contenues dans les listes sont 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ù la cartographie 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', '']
1
répondu jpp 2018-07-14 10:24:30