2009-10-11 11 views
9
def isBig(x): 
    if x > 4: 
     return 'apple' 
    else: 
     return 'orange' 

Esto funciona:Cómo asignar una variable en IF, y luego devolverla. (Python)

if isBig(y): return isBig(y) 

esto no funciona:

if fruit = isBig(y): return fruit 

¿Por qué no lo hace el segundo una obra !? Quiero un 1-liner. Excepto que el 1er llamará a la función DOS VECES.

¿Cómo hacer que sea 1 línea, sin llamar a la función dos veces?

+6

¿Por qué quieres un trazador de líneas? Los programas no mejoran porque tienen menos líneas. –

+0

Igual que http://stackoverflow.com/questions/1513436/what-should-i-use-instead-of-assignment-in-an-expression-in-python/1513987#1513987 – PaulMcG

+2

¿Tiene 100 de estos? No estarías escribiendo un analizador sintáctico, ¿verdad? Vea esta lista (http://nedbatchelder.com/text/python-parsers.html) del sitio web de Ned Batchelder. – PaulMcG

Respuesta

16

veo a alguien más ya ha señalado a mi viejo "asigno y ajuste" receta de libro de cocina, que se reduce en su versión más sencilla de:

class Holder(object): 
    def set(self, value): 
    self.value = value 
    return value 
    def get(self): 
    return self.value 

h = Holder() 

... 

if h.set(isBig(y)): return h.get() 

Sin embargo, esto fue pensada sobre todo para facilitar la transcripción entre Python y idiomas en los que la asignación se admite directamente en if o while.Si usted tiene "cientos" de dicho cheque y vuelta en una cascada, es mucho mejor que hacer algo completamente diferente:

hundreds = isBig, isSmall, isJuicy, isBlah, ... 

for predicate in hundreds: 
    result = predicate(y) 
    if result: return result 

o incluso algo así como

return next(x for x in (f(y) for f in hundreds) if x) 

si está bien a obtener una excepción StopIteration si se cumple ningún predicado, o

return next((x for x in (f(y) for f in hundreds) if x)), None) 

si None es el valor de retorno adecuada cuando se cumple ningún predicado , Etc.

Casi invariablemente, el uso (o incluso desear ;-) Holder el truco/idioma no es un "olor de diseño", que sugiere la búsqueda de un enfoque diferente y más Pythonic - el único caso en Holder es Justified es exactamente el caso especial para el que lo diseñé, es decir, el caso en el que desea mantener correspondencia estrecha entre el código de Python y algo que no es Python (está transcribiendo un algoritmo de referencia en Python y quiere que funcione primero antes de refactorizarlo en una forma más Pythonic, o estás escribiendo Python como un prototipo que se transcribirá en C++, C#, Java, etc., una vez que esté funcionando efectivamente).

0

Esto no funciona debido al diseño del lenguaje intencional, pero se puede utilizar this trick de moverse por esta decisión

0

El problema es que la operación de asignación no puede ser evaluado como teniendo un valor booleano. La instrucción if se basa en la capacidad de evaluar un booleano. Por ejemplo,

>>> fruit = 'apple' 
>>> bool(fruit = 'apple') 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 

/Users/jem/<ipython console> in <module>() 

TypeError: 'fruit' is an invalid keyword argument for this function 
>>> bool('a') 
True 
+0

No lo sé, porque tiene sentido. He votado por ti :) – TIMEX

+4

(No he votado negativamente, pero) La falta de un retorno booleano no es la causa de la imposibilidad de usarlo en una declaración 'if()'. Ambas limitaciones son _side-effects_ del lenguaje que define la asignación como una declaración en lugar de una expresión. –

2

Si desea codificar en PHP (o C), codifíquelo. No intente forzar sus métodos en otro idioma.

Uno de los principios básicos detrás de Python (en mi opinión) es su legibilidad. Usted debe utilizar:

fruit = isBig(y) 
if fruit: return fruit 

También debería mencionar que el uso de isXXX() es muy extraño; generalmente se usa para devolver valores booleanos. Especialmente en este caso donde lo está usando en una declaración IF.

+2

No considero ninguna versión más o menos legible, pero tal vez sea por experiencia. Además, en mi humilde opinión, es más "consistente" convertirlo en una expresión, ya que '=' se parece (y es interpretado por intérpretes y humanos, como) un operador (expresión implícita), en lugar de una función (enunciado implícito, aunque esto no lo es) t técnicamente cierto). –

+0

Francamente, no siempre puede usar el idioma que desea para un proyecto, por lo que esta es una de las respuestas menos útiles que he visto. Si pudiera votarte una docena de veces, lo haría. – Rabbit

+1

Conejo, si tiene que usar un idioma específico por cualquier razón, debe usarlo correctamente. Intentar calzar las construcciones en otro idioma es una idea estúpida. He visto cosas tan extrañas como '#define begin {' en código C porque los programadores de Pascal no querían adaptarse. Ese tipo de comportamiento hace que el código sea inútil en _ambos_ idiomas. – paxdiablo

8

El único trazador de líneas no funciona porque, en Python, la asignación (fruit = isBig(y)) es una declaración, no una expresión. En C, C++, Perl e innumerables otros idiomas es una expresión, y puedes ponerlo en un if o un while o lo que quieras, pero no en Python, porque los creadores de Python pensaban que esto se usaba con demasiada facilidad (o abusado) para escribir código "inteligente" (como lo intentas).

Además, su ejemplo es bastante tonto. isBig() siempre evaluará a true, ya que la única cadena que es falsa es la cadena vacía (""), por lo que su declaración if es inútil en este caso. Supongo que eso es solo una simplificación de lo que estás tratando de hacer. Simplemente haz esto:

tmp = isBig(y) 
if tmp: return tmp 

¿Es realmente mucho peor?

+2

Gracias. Por cierto, cuando tienes 100 como este, es mucho peor :) – TIMEX

+5

Cuando tienes 100 líneas como esta, suena un poco como si tu solución no fuera óptima, pero no puedo hablar sin saber lo que tú está haciendo –

+1

Al menos, alimente sus casos de prueba en una lista y repítalo para evitar escribirlos de esa manera. –

-3
print "apple" if x > 4 else "orange" 
+0

Esto no tiene nada que ver con la pregunta. –

Cuestiones relacionadas