Usando if, elif, else en List Comprehensions, Python

Creé la siguiente lista de comprensión en python:

[int(a[0].internal_value).lower() if type(a[0].internal_value) in (str,unicode) and a[0].internal_value.isdigit() == True else str(a[0].internal_value).lower() if type(a[0].internal_value) in (str,unicode) else int(a[0].internal_value) if type(a[0].internal_value) in (float,int) for a in ws.iter_rows() if a[0].internal_value  None] 

Tengo problemas tratando de construir el final, si la condición:

 else int(a[0].internal_value) if type(a[0].internal_value) in (float,int) 

Obtengo una syntax no válida si uso el condicional if en esa línea.

  if type(a[0].internal_value) in (float,int) 

Si elimino la sentencia if

 else int(a[0].internal_value) 

entonces parece funcionar bien. Necesito tener esa statement si allí.

Para mí, si no, si las condiciones son listas de comprensión, la forma de hacerlo es más simple si, sino condiciones:

 if i == x: do something elif i == y: do something elif i == z: do something 

Por regla general, no siempre tiene que tener un ‘else’ para cerrar una serie de oraciones condicionales. Me parece que mi código quiere un último “más” en la comprensión. ¿Estoy en lo correcto al afirmar eso? Y si es así, ¿hay una manera de construir un final más, si en una lista de python la comprensión en lugar de un final?

Está (ab) utilizando expresiones condicionales , y deben tener la forma true_expression if test else false_expression . Estas expresiones siempre producen un valor, a diferencia de una sentencia if compuesta.

Tenga en cuenta que no debe probar == True ; Las expresiones booleanas ya son verdaderas o falsas sin esa prueba. Tampoco use <> , ese operador ha quedado en desuso y se ha eliminado de Python 3 por completo. is not None embargo, al probar None , un singleton, que usaría is not None .

Estás probando contra los resultados de type() ; que parece que quieres usar las pruebas isinstance() lugar.

También está utilizando int() en los valores, y luego llama a .lower() en el resultado. No hay int.lower() método int.lower() , por lo que esas llamadas fallarán con un AttributeError .

Lo siguiente está más cerca de funcionar bien, a menos que haya más tipos que int , float , str o unicode :

 [int(a[0].internal_value) if isinstance(a[0].internal_value, (float, int)) or a[0].internal_value.isdigit() else str(a[0].internal_value).lower() for a in ws.iter_rows() if a[0].internal_value is not None] 

Sin embargo, prefiero la conversión para filtrar la función:

 def conversion(value): if isinstance(value, (float, int)): return int(value) return str(value).lower() 

luego usar eso en una lista de comprensión:

 [conversion(a[0].internal_value) for a in ws.iter_rows() if a[0].internal_value is not None] 

Podría ser más fácil si creas una función auxiliar para ayudarte. También quité == True y int().lower() . No creo que haya ningún beneficio en incluir toda la lógica en la comprensión de la lista, pero eso depende de usted.

 def helper(x): if type(x) in (str,unicode) and x.isdigit(): return int(x) elif type(x) in (str,unicode): return str(x).lower() elif type(x) in (float,int): return int(x) [helper(a[0].internal_value) for a in ws.iter_rows() if a[0].internal_value <> None]