2010-06-01 6 views
142

Aquí está el código que estaba tratando de convertir en una lista de comprensión:¿Es posible usar 'else' en una lista de comprensión de python?

table = '' 
for index in xrange(256): 
    if index in ords_to_keep: 
     table += chr(index) 
    else: 
     table += replace_with 

¿Hay alguna manera de agregar la declaración else a esta comprensión?

table = ''.join(chr(index) for index in xrange(15) if index in ords_to_keep) 

Respuesta

229

La sintaxis a if b else c es un operador ternario en Python que se evalúa como a si la condición b es cierto - de lo contrario, se evalúa como c . Puede ser utilizado en las declaraciones de comprensión:

>>> [a if a else 2 for a in [0,1,0,3]] 
[2, 1, 2, 3] 

Así, por tu ejemplo,

table = ''.join(chr(index) if index in ords_to_keep else replace_with 
       for index in xrange(15)) 
+9

Tenga en cuenta que esto sólo funciona en Python 2.5 y posteriores. –

+3

¡increíble! Tan útil. – professorDante

+6

También tenga en cuenta que el 'else' es necesario y no se puede omitir, porque siempre se requiere un valor resultante. – sebix

14

Si desea una else no desea filtrar la lista por comprensión, usted quiere que iterar sobre cada valor. Puede utilizar true-value if cond else false-value como la declaración en su lugar, y quitar el filtro de la final:

table = ''.join(chr(index) if index in ords_to_keep else replace_with for index in xrange(15)) 
1

Además, habría que tener la razón al concluir que una lista por comprensión es la forma más eficiente de hacer esto?

Quizás. Las listas de comprensión no son inherentemente computacionalmente eficientes. Todavía se está ejecutando en tiempo lineal.

He reducido significativamente el tiempo de cálculo cuando se trata de grandes conjuntos de datos reemplazando las listas de comprensión (especialmente las anidadas) con las estructuras de tipos for-loop/list-annexing que tienes arriba. En esta aplicación, dudo que notará una diferencia.

+1

woops, quise preguntar sobre el método de unión vs. + = en una cadena. – Josh

+0

Interesante. Esto (http://wiki.python.org/moin/PythonSpeed#Takeadvantageofinterpreteroptimizations) dice lo contrario. – kennytm

+0

@Josh: en la versión anterior de Python, el método join() es muy superior. Las versiones más nuevas del intérprete intentan optimizar el método + =, pero no estoy seguro de qué tan bien funcione. Casi siempre uso el método join(). –

6

Para utilizar el else en las listas por comprensión en la programación Python se puede probar el siguiente fragmento de código. Esto resolvería su problema, el fragmento se prueba en python 2.7 y python 3.5.

obj = ["Even" if i%2==0 else "Odd" for i in range(10)] 
0

grandes respuestas, pero sólo quería hablar de una Gotcha que "pase" palabras clave no funciona en la parte if/else de la lista-comprensión (como se ha escrito en los ejemplos mencionados anteriormente).

#works 
list1 = [10, 20, 30, 40, 50] 
newlist2 = [x if x > 30 else x**2 for x in list1 ] 
print(newlist2, type(newlist2)) 

#but this WONT work 
list1 = [10, 20, 30, 40, 50] 
newlist2 = [x if x > 30 else pass for x in list1 ] 
print(newlist2, type(newlist2)) 

Esto es probado en Python 3.4. error es la siguiente:

newlist2 = [x if x > 30 else pass for x in list1 ]          
SyntaxError: invalid syntax 

Por lo tanto, trate de evitar de paso-ES en las listas por comprensión

+0

El constructo if/else es solo una expresión en cuanto a la comprensión de la lista. Si quieres dejar los elementos, necesitas poner tu expresión en lugar de 'expr2' aquí' [expr1 para x en la lista1 si expr2] ' –

+0

Bueno, el pase funciona en un bloque if else normal, para mí, eso implica que funcionaría en todas partes también. Pero no tan en las listas de comprensión. – Plankton

+1

Pero este no es un bloque if/else normal. Es [una expresión] (https://docs.python.org/3/faq/programming.html#is-there-an-equivalent-of-c-s-ternary-operator). No puedes usar elif allí tampoco. –

Cuestiones relacionadas