Pregunta if / else en la lista de Python comprensión?


¿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. llevar a cabo una función.

536
2017-11-23 19:56


origen


Respuestas:


Puedes hacerlo totalmente, solo es un problema de pedido:

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

Tenga en cuenta que esto realmente utiliza una construcción de lenguaje diferente, una expresión condicional, que a su vez no es parte del sintaxis de comprensión, mientras que la if después de la for…in es parte de la lista de comprensiones y solía filtrar elementos de la fuente iterable.

Las expresiones condicionales se pueden usar en todo tipo de situaciones en las que desee elegir entre dos valores de expresión basados ​​en alguna condición. Esto hace lo mismo que operador ternario ?: que existe en otros idiomas. Por ejemplo:

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

824
2017-11-23 19:59



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 puede usar una lambda en línea.


34
2017-11-23 20:00



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úa a False para 0 y para True para todos los demás valores generados por la función range(). Por lo tanto, la comprensión de la lista se evalúa de la siguiente manera:

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

30
2017-10-07 21:37



El problema específico ya ha sido resuelto en respuestas anteriores, por lo que abordaré la idea general de usar condicionales dentro de la lista de comprensiones.

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:

valor  para  expresión1  Si  expresión2

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

valor1  Si  expresión1  más  valor2  para  expresión2

Siempre me resulta difícil recordar eso valor1 tiene que ser antes Si y valor2 tiene que ser después más. Mi cabeza quiere que ambos estén antes o después.

Supongo que está diseñado así porque se asemeja al lenguaje normal, p. "Quiero quedarme adentro Si llueve, más Quiero ir afuera"


3
2018-06-21 11:28



Las otras soluciones son geniales para una sola if / else construir. Sin embargo, las declaraciones ternarias dentro de la lista de comprensiones son posiblemente difíciles de leer.

El uso de una función ayuda a la legibilidad, pero dicha solución es difícil de ampliar o adaptar en un flujo de trabajo donde 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', '']

0
2017-07-14 10:24