¿Cuál es el equivalente de Python de && (lógico-y) en una declaración if?

10 minutos de lectura

Esto no funciona:

if cond1 && cond2:

  • Me parece que el intérprete debería, en lugar de imprimir un críptico “SyntaxError: sintaxis no válida”, detectar que el usuario ha utilizado && y sugiérales que tal vez quieran usar la palabra clave and en cambio. Lo mismo ocurre con cosas como ++ y otros operadores comunes de otros idiomas.

    – El arte de la guerra

    26 de septiembre de 2013 a las 17:28

  • @physicsmichael “debería haber una, y preferiblemente solo una, forma obvia de hacerlo”. import this

    – Nick T.

    14/09/2014 a las 20:24

  • and y or también se puede usar para evaluar la veracidad de expresiones que involucran más que solo valores booleanos. Para obtener más información, consulte esta publicación.

    – cs95

    29 de diciembre de 2018 a las 12:07

Avatar de usuario de ChristopheD
christopheD

Usar and en lugar de &&.

  • ¿Qué debo hacer para esto: si x==’n’ y y ==’a’ o y==’b’: ¿Funcionará? @ChristopheD

    – difractado

    02/04/2015 a las 15:35


  • @diffracteD: use paréntesis si desea anular la precedencia del operador estándar (que puede obtener información aquí: ibiblio.org/g2swap/byteofpython/read/operator-precedence.html)

    – ChristopheD

    02/04/2015 a las 21:51


  • Me gusta que David Titarenco haya dado un ejemplo de cortar y pegar

    – Alexx Roche

    27 mayo 2015 a las 16:33


  • Llegué aquí después de escribir ambos && y AND y obtuve un error (no esperaba que Python quisiera la palabra en minúsculas and).

    – Xeoncross

    22 de noviembre de 2016 a las 17:28

  • Creo que deberías usar & Ver: stackoverflow.com/questions/36921951/…

    – Chispa roja

    27 de julio de 2017 a las 20:24


Avatar de usuario de David Titarenco
david titarenco

usos de pitón and y or condicionales.

es decir

if foo == 'abc' and bar == 'bac' or zoo == '123':
  # do something

  • No olvides que python tampoco tiene (bueno, ¡y!)

    – inspectorG4dget

    21 de marzo de 2010 a las 2:54

  • ¿Su ejemplo se evalúa como “(si esto y esto) o aquello” O “si esto y (este o aquello)”?

    – Jeff

    19 de febrero de 2014 a las 18:04

  • @Jeff Tu primera forma. and tiene mayor precedencia que or.

    – Buge

    26 ago 2014 a las 19:05


  • @Buge parece que “o” está más arriba en la tabla que vinculaste

    – Mate

    4 de diciembre de 2017 a las 14:59

  • @Matt, la tabla va de la precedencia más baja a la más alta. Es más fácil recordar la precedencia si has estudiado álgebra booleana; “o” es suma y “y” es multiplicación.

    -Michael Stroud

    5 de diciembre de 2017 a las 19:02


Avatar de usuario de MSeifert
MSeifert

Recibo un error en el IF condicional. ¿Qué estoy haciendo mal?

Hay razón por la que obtienes un SyntaxError es que no hay && operador en Python. Asimismo || y ! son no es válido Operadores de Python.

Algunos de los operadores que puede conocer de otros lenguajes tienen un nombre diferente en Python. Los operadores lógicos && y || en realidad se llaman and y or. Del mismo modo, el operador de negación lógica ! se llama not.

Así que podrías simplemente escribir:

if len(a) % 2 == 0 and len(b) % 2 == 0:

o incluso:

if not (len(a) % 2 or len(b) % 2):

Alguna información adicional (que puede ser útil):

Resumí los “equivalentes” del operador en esta tabla:

+------------------------------+---------------------+
|  Operator (other languages)  |  Operator (Python)  |
+==============================+=====================+
|              &&              |         and         |
+------------------------------+---------------------+
|              ||              |         or          |
+------------------------------+---------------------+
|              !               |         not         |
+------------------------------+---------------------+

Ver también Documentación de Python: 6.11. operaciones booleanas.

Además de los operadores lógicos, Python también tiene operadores bit a bit/binarios:

+--------------------+--------------------+
|  Logical operator  |  Bitwise operator  |
+====================+====================+
|        and         |         &          |
+--------------------+--------------------+
|         or         |         |          |
+--------------------+--------------------+

No hay negación bit a bit en Python (solo el operador inverso bit a bit ~ – pero eso es no equivalente a not).

Ver también 6.6. Operaciones aritméticas unarias y bit a bit/binarias y 6.7. Operaciones aritméticas binarias.

Los operadores lógicos (como en muchos otros lenguajes) tienen la ventaja de que estos están cortocircuitados. Eso significa que si el primer operando ya define el resultado, entonces el segundo operador no se evalúa en absoluto.

Para mostrar esto, uso una función que simplemente toma un valor, lo imprime y lo devuelve nuevamente. Esto es útil para ver lo que realmente se evalúa debido a las declaraciones de impresión:

>>> def print_and_return(value):
...     print(value)
...     return value

>>> res = print_and_return(False) and print_and_return(True)
False

Como puede ver, solo se ejecuta una declaración de impresión, por lo que Python realmente ni siquiera miró el operando correcto.

Este no es el caso de los operadores binarios. Esos siempre evalúan ambos operandos:

>>> res = print_and_return(False) & print_and_return(True);
False
True

Pero si el primer operando no es suficiente, entonces, por supuesto, se evalúa el segundo operador:

>>> res = print_and_return(True) and print_and_return(False);
True
False

Para resumir esto aquí hay otra tabla:

+-----------------+-------------------------+
|   Expression    |  Right side evaluated?  |
+=================+=========================+
| `True` and ...  |           Yes           |
+-----------------+-------------------------+
| `False` and ... |           No            |
+-----------------+-------------------------+
|  `True` or ...  |           No            |
+-----------------+-------------------------+
| `False` or ...  |           Yes           |
+-----------------+-------------------------+

El True y False representar lo que bool(left-hand-side) devoluciones, no tienen que ser True o Falsesolo necesitan regresar True o False cuando bool se les llama (1).

Así que en Pseudo-Code(!) el and y or funciones funcionan así:

def and(expr1, expr2):
    left = evaluate(expr1)
    if bool(left):
        return evaluate(expr2)
    else:
        return left

def or(expr1, expr2):
    left = evaluate(expr1)
    if bool(left):
        return left
    else:
        return evaluate(expr2)

Tenga en cuenta que este es un pseudocódigo, no un código de Python. En Python no puedes crear funciones llamadas and o or porque estas son palabras clave. Además, nunca debe usar “evaluar” o if bool(...).

Personalizando el comportamiento de tus propias clases

Esta implícita bool La llamada se puede usar para personalizar cómo se comportan sus clases con and, or y not.

Para mostrar cómo se puede personalizar esto, uso esta clase que nuevamente prints algo para rastrear lo que está sucediendo:

class Test(object):
    def __init__(self, value):
        self.value = value

    def __bool__(self):
        print('__bool__ called on {!r}'.format(self))
        return bool(self.value)

    __nonzero__ = __bool__  # Python 2 compatibility

    def __repr__(self):
        return "{self.__class__.__name__}({self.value})".format(self=self)

Entonces, veamos qué sucede con esa clase en combinación con estos operadores:

>>> if Test(True) and Test(False):
...     pass
__bool__ called on Test(True)
__bool__ called on Test(False)

>>> if Test(False) or Test(False):
...     pass
__bool__ called on Test(False)
__bool__ called on Test(False)

>>> if not Test(True):
...     pass
__bool__ called on Test(True)

Si no tienes un __bool__ entonces Python también verifica si el objeto tiene un __len__ método y si devuelve un valor mayor que cero. Puede ser útil saberlo en caso de que cree un contenedor de secuencia.

Ver también 4.1. Pruebas de valor de verdad.

NumPy arreglos y subclases

Probablemente un poco más allá del alcance de la pregunta original, pero en caso de que esté tratando con matrices o subclases NumPy (como Pandas Series o DataFrames), entonces el implícito bool llamada levantará la temida ValueError:

>>> import numpy as np
>>> arr = np.array([1,2,3])
>>> bool(arr)
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
>>> arr and arr
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

>>> import pandas as pd
>>> s = pd.Series([1,2,3])
>>> bool(s)
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
>>> s and s
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

En estos casos se puede utilizar la lógica y función de NumPy que realiza un elemento-sabio and (o or):

>>> np.logical_and(np.array([False,False,True,True]), np.array([True, False, True, False]))
array([False, False,  True, False])
>>> np.logical_or(np.array([False,False,True,True]), np.array([True, False, True, False]))
array([ True, False,  True,  True])

Si solo estás tratando con matrices booleanas también podría usar los operadores binarios con NumPy, estos realizan comparaciones de elementos (pero también binarias):

>>> np.array([False,False,True,True]) & np.array([True, False, True, False])
array([False, False,  True, False])
>>> np.array([False,False,True,True]) | np.array([True, False, True, False])
array([ True, False,  True,  True])

(1)

Que el bool la llamada a los operandos tiene que volver True o False no es completamente correcto. Es solo el primer operando que necesita devolver un booleano en su __bool__ método:

class Test(object):
    def __init__(self, value):
        self.value = value

    def __bool__(self):
        return self.value

    __nonzero__ = __bool__  # Python 2 compatibility

    def __repr__(self):
        return "{self.__class__.__name__}({self.value})".format(self=self)

>>> x = Test(10) and Test(10)
TypeError: __bool__ should return bool, returned int
>>> x1 = Test(True) and Test(10)
>>> x2 = Test(False) and Test(10)

Eso es porque and en realidad devuelve el primer operando si el primer operando se evalúa como False y si se evalúa como True luego devuelve el segundo operando:

>>> x1
Test(10)
>>> x2
Test(False)

Del mismo modo para or pero al revés:

>>> Test(True) or Test(10)
Test(True)
>>> Test(False) or Test(10)
Test(10)

Sin embargo, si los usa en un if declaración de la if también llamará implícitamente bool sobre el resultado Entonces, estos puntos más finos pueden no ser relevantes para usted.

Dos comentarios:

  • Usar and y or para operaciones lógicas en Python.
  • Use 4 espacios para sangrar en lugar de 2. Se lo agradecerá más tarde porque su código se verá prácticamente igual que el código de todos los demás. Ver PEP 8 para más detalles.

Avatar de usuario de Big Red
Gran rojo

Fui con una solución puramente matemática:

def front_back(a, b):
  return a[:(len(a)+1)//2]+b[:(len(b)+1)//2]+a[(len(a)+1)//2:]+b[(len(b)+1)//2:]

  • Esta no es una respuesta a la pregunta real.

    – Mateo Lee

    26/10/2017 a las 17:33

Avatar de usuario de MarianD
MarianD

Tu usas and y or para realizar operaciones lógicas como en C, C++. como literalmente and es && y or es ||.


Echa un vistazo a este divertido ejemplo,

Digamos que quieres construir puertas lógicas en Python:

def AND(a,b):
    return (a and b) #using and operator

def OR(a,b):
    return (a or b)  #using or operator

Ahora intenta llamarlos:

print AND(False, False)
print OR(True, False)

Esto generará:

False
True

¡Espero que esto ayude!

  • Esta no es una respuesta a la pregunta real.

    – Mateo Lee

    26/10/2017 a las 17:33

avatar de usuario de bstpierre
bstpierre

Probablemente este no sea el mejor código para esta tarea, pero está funcionando:

def front_back(a, b):

 if len(a) % 2 == 0 and len(b) % 2 == 0:
    print a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):]

 elif len(a) % 2 == 1 and len(b) % 2 == 0:
    print a[:(len(a)/2)+1] + b[:(len(b)/2)] + a[(len(a)/2)+1:] + b[(len(b)/2):] 

 elif len(a) % 2 == 0 and len(b) % 2 == 1:
     print a[:(len(a)/2)] + b[:(len(b)/2)+1] + a[(len(a)/2):] + b[(len(b)/2)+1:] 

 else :
     print a[:(len(a)/2)+1] + b[:(len(b)/2)+1] + a[(len(a)/2)+1:] + b[(len(b)/2)+1:]

¿Ha sido útil esta solución?