2010-04-03 12 views
7

que tienen la siguiente función lambda:Python lambda regresar Ninguno en lugar de cadena vacía

f = lambda x: x == None and '' or x 

debería devolver una cadena vacía si recibe Ninguno como el argumento, el argumento o si no hay ninguno.

Por ejemplo:

>>> f(4) 
4 
>>> f(None) 
>>> 

Si llamo f (ninguno) en lugar de obtener una cadena vacía consigo Ninguno. Imprimí el tipo de lo que devolvió la función y obtuve NoneType. Esperaba cadena.

tipo ('') devuelve la cadena, por lo que me gustaría saber por qué la lambda no devuelve una cadena vacía cuando paso ninguno como argumento.

Soy bastante nuevo en lambdas, así que podría haber entendido mal algunas cosas sobre cómo funcionan.

+2

Usted ha cometido uno de los errores clásicos ... – PaulMcG

Respuesta

17

utilice el caso de los demás construir

f = lambda x:'' if x is None else x 
2

Aquí no hay lambdas. Es la expresión pythonic if/else que está utilizando allí.

(condition) and (expression1) or (expression2) la mayoría de las veces significa el (condition) ? (expression1) : (expression2) que cabría esperar, excepto cuando expression1 se evalúa como False.

Esto se debe a que todo se evalúa en orden. Si condition falla, se evalúa expression1. Si es True, se devuelve, debido a la evaluación de cortocircuito, de ahí el comportamiento esperado. Si no, se devuelve expression2. '' se evalúa como Falso.

+0

Sí, y el patrón no es muy pitónico ... ¡no lo use! ¡Manténlo simple, estúpido! –

8

El problema en su caso es que '' está considerado como booleano False. bool ('') == Falso. Puede utilizar

f =lambda x:x if x is not None else '' 
2

Trate short-circuit evaluation:

>>> g = lambda x: x or '' 
>>> g(3) 
3 
>>> g(None) 
'' 
>>> # beware that ... 
>>> g(0) 
'' 
+0

No creo que 'g (0)' devuelva lo que OP quiere. –

2

Python da and una prioridad más alta que or, por lo que los paréntesis caer aquí:

lambda x: (x == None and '') or x 

Cuando pasó None, esto se convierte en (True and '') or None. Los operadores booleanos de Python funcionan devolviendo un argumento u otro (de donde este pequeño truco), por lo que esto se reduce a '' or None, y finalmente None.

Este pequeño truco proviene de la espalda antes de Python 2.5, que no tenía el conditional operator. La advertencia, con la que acaba de toparse, es que no se comporta como se esperaba cuando la rama True tiene un valor de False. A menos que le preocupe Python ≤ 2.4, simplemente use el operador condicional.

4

El problema es que Python considera la cadena vacía como False.Cuando se pasa Ninguno para su función, se evalúa como:

None == None and '' or None 

cuales (eficacia) se convierte en:

True and False or None 

a continuación:

False or None 

y finalmente:

None 

Una solución sería:

lambda x: x if x is not None else '' 

Si conoces x será una cadena o ninguno, entonces se puede aprovechar el hecho de que ninguno es también un valor Falso en Python:

lambda x: x or '' 
Cuestiones relacionadas