web-dev-qa-db-fra.com

L'équivalent Python de && (logical-and) dans une instruction if

Voici mon code:

def front_back(a, b):
  # +++your code here+++
  if len(a) % 2 == 0 && len(b) % 2 == 0:
    return a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):] 
  else:
    #todo! Not yet done. :P
  return

Je reçois une erreur dans le SI conditionnel. Qu'est-ce que je fais mal?

740
delete

Vous voudriez and au lieu de &&.

1307
ChristopheD

Python utilise and et or conditionals.

c'est à dire.

if foo == 'abc' and bar == 'bac' or Zoo == '123':
  # do something
210
David Titarenco

Deux commentaires:

  • Utilisez and et or pour les opérations logiques en Python.
  • Utilisez 4 espaces pour mettre en retrait au lieu de 2. Vous vous en remercierez plus tard, car votre code ressemblera beaucoup à celui de tous les autres. Voir PEP 8 pour plus de détails.
36
istruble

Je reçois une erreur dans le SI conditionnel. Qu'est-ce que je fais mal?

La raison pour laquelle vous obtenez un SyntaxError est qu’il n’ya pas d’opérateur && en Python. De même, || et ! sont non valides Python opérateurs.

Certains des opérateurs que vous connaissez peut-être d'autres langues portent un nom différent en Python. Les opérateurs logiques && et || s'appellent en fait and et or. De même, l'opérateur de négation logique ! s'appelle not.

Pour que vous puissiez simplement écrire:

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

ou même:

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

Quelques informations supplémentaires (qui pourraient être utiles):

J'ai résumé l'opérateur "équivalents" dans ce tableau:

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

Voir aussi Documentation Python: 6.11. Opérations booléennes .

Outre les opérateurs logiques, Python possède également des opérateurs au niveau du bit/binaire:

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

Il n’ya pas de négation au niveau du bit dans Python (seulement l’opérateur inverse au niveau du bit ~ - mais c’est pas équivalent à not).

Voir aussi 6.6. Opérations arithmétiques unaires et bits/binaires et 6.7. Opérations arithmétiques binaires .

Les opérateurs logiques (comme dans beaucoup d'autres langages) ont l'avantage d'être court-circuités. Cela signifie que si le premier opérande définit déjà le résultat, le second opérateur n'est pas du tout évalué.

Pour montrer cela, j'utilise une fonction qui prend simplement une valeur, l'imprime et la renvoie à nouveau. C'est pratique pour voir ce qui est réellement évalué à cause des instructions print:

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

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

Comme vous pouvez voir, une seule instruction print est exécutée, donc Python n'a même pas regardé l'opérande correct.

Ce n'est pas le cas pour les opérateurs binaires. Ceux-ci évaluent toujours les deux opérandes:

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

Mais si le premier opérande ne suffit pas, alors bien sûr, le deuxième opérateur est évalué:

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

Pour résumer ceci, voici un autre tableau:

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

Les variables True et False représentent ce que bool(left-hand-side) renvoie, elles ne doivent pas nécessairement être True ou False, elles doivent simplement renvoyer True ou False lorsque bool est appelé (1).

Ainsi, dans le pseudo-code (!), Les fonctions and et or fonctionnent comme suit:

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)

Notez qu'il s'agit d'un pseudo-code et non du code Python. Dans Python, vous ne pouvez pas créer de fonctions appelées and ou or, car il s'agit de mots-clés. De plus, vous ne devriez jamais utiliser "évaluer" ou if bool(...).

Personnaliser le comportement de vos propres classes

Cet appel implicite bool peut être utilisé pour personnaliser le comportement de vos classes avec and, or et not.

Pour montrer comment cela peut être personnalisé, j'utilise cette classe qui encore print est quelque chose qui permet de suivre ce qui se passe:

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)

Voyons donc ce qui se passe avec cette classe en combinaison avec ces opérateurs:

>>> 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 vous n'avez pas de méthode __bool__, alors Python vérifie également si l'objet a une méthode __len__ et renvoie une valeur supérieure à zéro. Cela peut être utile de savoir si vous créez un conteneur de séquence.

Voir aussi 4.1. Test de valeur de vérité .

Tableaux et sous-classes NumPy

Probablement un peu au-delà de la question initiale mais si vous avez affaire à des tableaux ou des sous-classes NumPy (comme Pandas Series ou DataFrames), alors l'appel implicite bool soulèvera le redoutable 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().

Dans ces cas, vous pouvez utiliser la fonction logique et de NumPy, qui exécute une fonction élémentaire and (ou 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 vous utilisez uniquement des tableaux booléens , vous pouvez également utiliser les opérateurs binaires avec NumPy, ceux-ci effectuent des comparaisons élément par élément (mais aussi binaire):

>>> 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)

Le fait que l'appel bool sur les opérandes doit renvoyer True ou False n'est pas tout à fait correct. C'est juste le premier opérande qui doit retourner un booléen dans sa méthode __bool__:

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)

En effet, and renvoie le premier opérande si le premier opérande est évalué à False et s'il est évalué à True, il renvoie le deuxième opérande:

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

De même pour or mais en sens inverse:

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

Toutefois, si vous les utilisez dans une instruction if, la if appellera également implicitement bool sur le résultat. Donc, ces points plus fins peuvent ne pas être pertinents pour vous.

27
MSeifert

Je suis allé avec une solution purement mathématique:

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:]
10
Big Red

Vous utilisez and ET or pour effectuer des opérations logiques comme en C, C++. Comme littéralement and EST _&&_ ET or EST _||.


Jetez un oeil à cet exemple amusant,

Dites que vous voulez construire des portes logiques en Python:

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

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

Maintenant, essayez de les appeler:

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

Cela produira:

_False
True
_

J'espère que ça aide!

8
geekidharsh

Ce n'est probablement pas le meilleur code pour cette tâche, mais ça marche -

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:]
5

Dans une "instruction If" dans Python, vous utiliseriez et, ou, pas et ceux-ci sont équivalents à &&, ||,! opérateurs logiques qui sont utilisés dans d'autres langages de programmation

0
masterpianist