Si / else en la lista de comprensión de Python?

¿Cómo puedo hacer lo siguiente en Python?

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

Esencialmente:

  1. Reemplace todos los Nones con cadenas vacías, y luego
  2. realizar una función.

Puedes hacerlo totalmente, es solo un problema de pedido:

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

En general,

 [f(x) if condition else g(x) for x in sequence] 

Y, para listas de comprensión con condiciones solamente,

 [f(x) for x in sequence if condition] 

Tenga en cuenta que esto en realidad utiliza una construcción de lenguaje diferente, una expresión condicional , que en sí misma no es parte de la syntax de comprensión , mientras que el if the for…in es parte de la lista de comprensión y se usa para filtrar elementos de la fuente iterable.


Las expresiones condicionales se pueden utilizar en todo tipo de situaciones en las que desea elegir entre dos valores de expresión en función de alguna condición. Esto hace lo mismo que el operador ternario ?: Que existe en otros idiomas . Por ejemplo:

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

De una sola mano:

 def change(f): if f is None: return unicode(f.strip()) else: return '' row = [change(x) for x in row] 

Aunque entonces tienes:

 row = map(change, row) 

O puedes usar un lambda en línea.

Aquí hay otro ejemplo ilustrativo:

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

Explota el hecho de que if i evalúo False para 0 y True para todos los demás valores generados por la función range() . Por lo tanto la lista de comprensión se evalúa de la siguiente manera:

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

El problema específico ya se resolvió en las respuestas anteriores, por lo que abordaré la idea general de usar condicionales dentro de la lista de comprensión.

Aquí hay un ejemplo que muestra cómo se pueden escribir los condicionales dentro de una lista de comprensión:

 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 

Tenga en cuenta que en la primera lista de comprensión para X_non_str , el orden es:

expresión para el elemento en iterable si la condición

y en la última lista de comprensión de X_str_changed , el orden es:

expresión1 si la condición es más expresión2 para el elemento en iterable

Siempre me resulta difícil recordar que expresseion1 tiene que ser antes si y expression2 tiene que ser después de otra cosa . Mi cabeza quiere que ambos sean antes o después.

Supongo que está diseñado así porque se asemeja al lenguaje normal, por ejemplo, “Quiero quedarme dentro si llueve, de lo contrario , quiero salir”.

Las otras soluciones son excelentes para una sola construcción if / else . Sin embargo, las afirmaciones ternarias dentro de las listas de comprensión son posiblemente difíciles de leer.

El uso de una función facilita la lectura, pero es difícil extender o adaptar una solución de este tipo en un flujo de trabajo en el que la asignación es una entrada. Un diccionario puede aliviar estas preocupaciones:

 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', ''] 
 # coding=utf-8 def my_function_get_list(): my_list = [0, 1, 2, 3, 4, 5] # You may use map() to convert each item in the list to a string, # and then join them to print my_list print("Affichage de my_list [{0}]".format(', '.join(map(str, my_list)))) return my_list my_result_list = [ ( number_in_my_list + 4, # Condition is False : append number_in_my_list + 4 in my_result_list number_in_my_list * 2 # Condition is True : append number_in_my_list * 2 in my_result_list ) [number_in_my_list % 2 == 0] # [Condition] If the number in my list is even for number_in_my_list in my_function_get_list() # For each number in my list ] print("Affichage de my_result_list [{0}]".format(', '.join(map(str, my_result_list)))) 

(venv) $ python list_comp.py
Affichage de my_list [0, 1, 2, 3, 4, 5]
Affichage de my_result_list [0, 5, 4, 7, 8, 9]

Entonces, para usted: row = [('', unicode(x.strip()))[x is not None] for x in row]