while switch statement for examples example else python python-2.7 if-statement control-structure

statement - switch python



Python-Si no es una declaraciĆ³n con 0.0 (6)

Como está utilizando None para indicar que "este parámetro no está configurado", eso es exactamente lo que debe verificar al usar la palabra clave is :

def square(x=None): if x is None: print "you have not entered x" else: y=x**2 return y

La comprobación del tipo es engorrosa y propensa a errores, ya que tendría que comprobar todos los posibles tipos de entrada , no solo int .

Tengo una pregunta con respecto a if not statement en Python 2.7 .

He escrito un código y lo uso if not declaraciones. En una parte del código que escribí, me refiero a una función que incluye una declaración if not para determinar si se ha ingresado una palabra clave opcional.

Funciona bien, excepto cuando 0.0 es el valor de la palabra clave. Entiendo que esto se debe a que 0 es una de las cosas que se considera "no". Mi código probablemente sea demasiado largo para publicarlo, pero este es un ejemplo análogo (aunque simplificado):

def square(x=None): if not x: print "you have not entered x" else: y=x**2 return y list=[1, 3, 0 ,9] output=[] for item in list: y=square(item) output.append(y) print output

Sin embargo, en este caso me quedé con:

you have not entered x [1, 9, None, 81]

Donde como me gustaría obtener:

[1, 9, 0, 81]

En el ejemplo anterior, podría usar una lista de comprensión, pero suponiendo que quería usar la función y obtener el resultado deseado, ¿cómo podría hacerlo?

Un pensamiento que tuve fue:

def square(x=None): if not x and not str(x).isdigit(): print "you have not entered x" else: y=x**2 return y list=[1, 3, 0 ,9] output=[] for item in list: y=square(item) output.append(y) print output

Esto funciona, pero parece una forma un poco torpe de hacerlo. Si alguien tiene otra manera que sería agradable estaría muy agradecido.


Por lo que yo entiendo, quieres ver los casos donde no se dio entrada:

if x is None: ...

y los casos donde no es un número. Con el segundo terminarás con algunos problemas, porque tal vez quieras permitir numpy-ndarrays en el futuro u otra cosa, normalmente solo te sugiero que no te molestes en excluir otras clases, pero si solo quieres permitir int y float luego usar

if isinstance(x, (int, float, ...)): ...

el ... representa otras clases permitidas (quizás Decimal o Fractions ).

Entonces podrías escribirlo como:

if x is not None and isinstance(x, (int, float)): return x**2 else: print "you have not entered x"

Como None no es un int o un float , también puede omitir la primera condición y escribir:

if isinstance(x, (int, float)): ...


if x is None: print ''x is None''


U puede manejar excepciones aquí. Haga un código como este

def square(x): if not x: print "you have not entered x" else: try: int(y)=x**2 return y except TypeError: pass list=[1, 3, 0 ,9] output=[]


Si puede identificar un único tipo con el que todas las entradas deben ser compatibles , puede convertirlo y manejar la excepción:

def square(x=None): try: return float(x)**2 except TypeError: print "You did not enter a real number" return None # Explicit is better than implicit

Esto tiene algunas ventajas.

  • Impone que lo que sea que el usuario le envíe sea compatible con float . Puede ser cualquier número, una cadena que contenga un número ( ''5.0'' ) o cualquier otra cosa que pueda convertirse en un float . (las instancias float se devuelven sin cambios).
  • Es sencillo. No hay magia extraña sucediendo en tu método. No estás rompiendo pato escribiendo. Simplemente está haciendo cumplir sus requisitos para que todo funcione bien.
  • No es vulnerable a las trampas involucradas con realmente verificar el tipo. Sus interlocutores pueden decirle cómo su tipo personalizado se convierte en float . Python proporciona el método mágico __float__ , por lo que si sus usuarios tienen tipos exóticos y necesitan usar su función, no se hundirán.
  • Es idiomático Los programadores de Python con experiencia esperarán este tipo de código; sigue el principio de "más fácil de pedir perdón que de permiso".

Un lado ( tal vez ):

Si None es un valor no válido, no lo convierta en un valor predeterminado. Simplemente obligue a la persona que llama a proporcionar su opinión:

def square(x): try: return float(x)**2 except TypeError: print "You did not enter a real number" return None


Problema

Lo entiendes bien not 0 (y not 0.0 ) devuelve True en Python . Se puede hacer una prueba simple para ver esto:

a = not 0 print(a) Result: True

Por lo tanto, el problema se explica. Esta línea:

if not x:

Debe ser cambiado a otra cosa.

Soluciones

Hay dos formas de solucionar el problema. Solo voy a enumerarlos de lo que creo que es la mejor solución hasta las últimas soluciones posibles:


  1. Para manejar todos los casos válidos posibles .

    Como square debería esperar un número de entrada con la exclusión de un número complejo y debería return un error de lo contrario, creo que la mejor solución es evaluar el uso if not isinstance(x, numbers.Number) or isinstance(x, numbers.Complex):

    def square(x=None): if not isinstance(x, numbers.Number) or isinstance(x, numbers.Complex): # this sums up every number type, with the exclusion of complex number print ("you have not entered x") else: y=x**2 return y list=[1, 3, 0 ,9] output=[] for item in list: y=square(item) output.append(y) print (output)

    numbers.Number es la clase abstracta para verificar si el argumento x es un número (crédito a Copperfield por señalar esto).

    Extracto de la documentación de Python Standard Library explica exactamente lo que necesita, con la excepción del número complejo:

    números de clase . Número

    La raíz de la jerarquía numérica . Si solo quiere comprobar si un argumento x es un número, sin importar de qué tipo , use isinstance (x, Number) .

    Pero no desea que la entrada sea un número complejo. Por lo tanto, solo omita el uso or isinstance(x, numbers.Complex)

    De esta manera, escribes la definition de square exactamente de la manera que quieres. Esta solución, creo, es la mejor solución en virtud de su amplitud .


  1. Para manejar solo los tipos de datos que desea manejar .

    Si tiene una lista de tipos de datos de entrada válidos, también puede colocar solo los tipos de datos específicos que desea manejar. Es decir, no desea manejar los casos para tipos de datos que no sean los que ha especificado. Ejemplos:

    if not instance(x, int): #just handle int if not instance(x, (int, float)): #just handle int and float if not instance(x, (numbers.Integral, numbers.Rational)): #just handle integral and rational, not real or complex

    Puede cambiar / ampliar fácilmente la condición anterior para diferentes tipos de datos que desee incluir o excluir, según su necesidad. Esta solución, creo, es la segunda mejor por la virtud de su personalización para su comprobación de validez .

    (El código anterior se realiza de forma más Pythonical , como lo sugiere el gato )


  1. No maneja casos imposibles: usted sabe lo que los usuarios no pondrían como entrada .

    Piénselo más libremente, si sabe (no los tipos de datos que desea manejar como en la segunda solución) sino los tipos de datos que el usuario no pondría, entonces puede tener una verificación de condición más flexible como esta:

    if not isinstance(x, numbers.Number): # this is ok, because the user would not put up complex number

    Esta solución, creo, es la tercera mejor por la virtud de ser una de las comprobaciones más simples pero poderosas .

    El único inconveniente de esta solución es que no maneja el tipo complejo. Por lo tanto, solo se puede implementar debido al hecho de que los usuarios no tendrían un número complejo como entrada.


  1. Para manejar los errores de entrada solo para las posibles entradas conocidas que pueden causar los errores .

    Por ejemplo, si usted sabe que x es siempre int o None , y por lo tanto, el único error de entrada posible es None , entonces simplemente podemos escribir la lógica para evitar que se evalúe solo cuando x es None como este:

    def square(x=None): if x is None: print ("you have not entered x") else: y=x**2 return y list=[1, 3, 0 ,9] output=[] for item in list: y=square(item) output.append(y) print (output)

    Esta solución tiene la virtud de ser la más simple .

    ... y, sin embargo, es el más peligroso para ser utilizado si no sabes exactamente lo que los usuarios pondrían para la entrada. De lo contrario, esta solución está bien y también es la más simple.

    Su solución, creo que más o menos pertenece a esta categoría. Ya sabe qué aportaciones dará el usuario y qué no. Por lo tanto, usando esta solución o su propia solución:

    if not x and not str(x).isdigit():

    Está bien, excepto que la solución de ejemplo es más simple

En su caso, puede usar cualquier solución anterior para obtener:

[1, 9, 0, 81]

(Nota al margen: trato de formatear las soluciones para que se vean como "soluciones canónicas" para facilitar la lectura. De esta manera, aquellos que tienen las mismas preguntas y visitan esta página en el futuro pueden encontrar las soluciones más completas y legible)