l'équivalent Python de && (et logique) dans une instruction if
-
21-09-2019 - |
Question
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?
La solution
Vous voulez and
au lieu de &&
.
Autres conseils
Python utilise conditionals de and
et or
.
i.e..
if foo == 'abc' and bar == 'bac' or zoo == '123':
# do something
Deux commentaires:
- Utilisation
and
etor
pour les opérations logiques dans python. - Utilisez 4 espaces pour indenter au lieu de 2. Vous vous remercierez plus tard parce que votre code ressemblera à peu près le même que le code de tout le monde. Voir PEP 8 pour plus de détails.
Je reçois une erreur dans le SI conditionnel. Qu'est-ce que je fais mal?
Il y a des raisons que vous obtenez un SyntaxError
est qu'il n'y a pas d'opérateur de &&
en Python. De même ||
et !
sont non valides les opérateurs Python.
Certains opérateurs vous savez peut-être d'autres langues ont un nom différent en Python.
Les opérateurs logiques &&
et ||
sont effectivement appelés and
et or
.
De même, l'opérateur de négation logique !
est appelée not
.
Vous pouvez 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 pourrait être utile):
Je récapitulé l'opérateur « équivalents » dans ce tableau:
+------------------------------+---------------------+
| Operator (other languages) | Operator (Python) |
+==============================+=====================+
| && | and |
+------------------------------+---------------------+
| || | or |
+------------------------------+---------------------+
| ! | not |
+------------------------------+---------------------+
Voir aussi documentation Python: 6.11. Les opérations booléennes .
Outre les opérateurs logiques Python a aussi les opérateurs binaires / binaires:
+--------------------+--------------------+
| Logical operator | Bitwise operator |
+====================+====================+
| and | & |
+--------------------+--------------------+
| or | | |
+--------------------+--------------------+
Il n'y a pas négation logique en Python (juste l'opérateur inverse ~
bit - mais qui est pas équivalent à not
).
Voir aussi 6.6. arithmétique unaire et binaire / opérations binaires et 6,7. opérations arithmétiques binaires .
Les opérateurs logiques (comme dans beaucoup d'autres langues) ont l'avantage que ce sont court-circuitées. Cela signifie que si le premier opérande définit déjà le résultat, le deuxième opérateur n'est pas évalué du tout.
Pour montrer cela, j'utilise une fonction qui prend simplement une valeur, l'imprime et il retourne à nouveau. Ceci est pratique pour voir ce qui est en fait évalué en raison des déclarations d'impression:
>>> def print_and_return(value):
... print(value)
... return value
>>> res = print_and_return(False) and print_and_return(True)
False
Comme vous pouvez le voir qu'une seule instruction d'impression est exécutée, si Python n'a vraiment pas l'air même à l'opérande de droite.
Ce n'est pas le cas pour les opérateurs binaires. Les exploitez toujours les deux opérandes:
>>> res = print_and_return(False) & print_and_return(True);
False
True
Mais si le premier opérande ne suffit donc pas, 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 cette voici une autre table:
+-----------------+-------------------------+
| Expression | Right side evaluated? |
+=================+=========================+
| `True` and ... | Yes |
+-----------------+-------------------------+
| `False` and ... | No |
+-----------------+-------------------------+
| `True` or ... | No |
+-----------------+-------------------------+
| `False` or ... | Yes |
+-----------------+-------------------------+
Le True
et False
représentent ce que bool(left-hand-side)
les rendements, ils ne doivent pas être True
ou False
, ils ont juste besoin de retourner True
ou False
quand bool
est appelé sur eux (1).
dans le code pseudo-fonctions de and
et or
fonctionnent comme ceux-ci (!):
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 que ce pseudo-code pas de code Python. En Python, vous ne pouvez pas créer des fonctions appelées and
ou or
parce que ce sont des mots-clés.
Aussi, vous ne devez jamais utiliser « évaluer » ou if bool(...)
.
Personnalisation du comportement de vos propres classes
Cet appel implicite bool
peut être utilisé pour personnaliser la façon dont se comportent vos classes avec and
, or
et not
.
Pour montrer comment cela peut être personnalisé J'utilise cette classe qui print
s quelque chose de nouveau pour 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)
Alors, nous allons voir 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 ne disposez pas d'une méthode __bool__
puis Python vérifie également si l'objet a une méthode __len__
et si elle retourne une valeur supérieure à zéro.
Cela pourrait être utile de savoir si vous créez un conteneur de séquence.
Voir aussi 4.1. Vérité valeur Test .
numpy tableaux et sous-classes
Probablement un peu au-delà de la portée de la question initiale, mais au cas où vous avez affaire à des tableaux ou des sous-classes numpy (comme Pandas série ou DataFrames) puis l'appel implicite bool
soulèvera la ValueError
redoutée:
>>> 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 ce cas, vous pouvez utiliser la logique et la fonction de NumPy qui effectue un and
élément par élément (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 traitez juste avec tableaux booléens vous pouvez également utiliser les opérateurs binaires avec NumPy, ceux-ci n'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)
Que l'appel bool
sur les opérandes doit retourner True
ou False
n'est pas tout à fait correct. Il est juste le premier opérande qui doit retourner une valeur booléenne dans c'est la méthode de __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)
C'est parce que and
retourne en fait le premier opérande si le premier opérande évalue à False
et si elle évalue à True
il renvoie le deuxième opérande:
>>> x1
Test(10)
>>> x2
Test(False)
De même pour or
mais juste l'inverse:
>>> Test(True) or Test(10)
Test(True)
>>> Test(False) or Test(10)
Test(10)
Toutefois, si vous les utilisez dans une instruction if
le if
également appeler implicitement bool
sur le résultat. Ainsi, ces subtilités peuvent ne pas être pertinents pour vous.
Je suis allé avec une solution mathématique purlely:
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:]
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 Logic Portes 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)
Affichera:
False
True
Hope this helps!
C'est probablement pas le meilleur code pour cette tâche, mais travaille -
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:]
Dans une "déclaration Si" en Python vous utilisez et, ou, pas et ceux-ci sont équivalentes à &&, ||, les opérateurs logiques qui sont utilisés dans d'autres langages de programmation
L'utilisation de « et » à condition. J'utilise souvent ce lors de l'importation dans Jupyter Notebook:
def find_local_py_scripts():
import os # does not cost if already imported
for entry in os.scandir('.'):
# find files ending with .py
if entry.is_file() and entry.name.endswith(".py") :
print("- ", entry.name)
find_local_py_scripts()
- googlenet_custom_layers.py
- GoogLeNet_Inception_v1.py
Un seul &
(pas de double &&
) est assez ou comme la réponse haut suggère que vous pouvez utiliser « et ».
J'ai aussi trouvé cela dans Pandas
cities['Is wide and has saint name'] = (cities['Population'] > 1000000)
& cities['City name'].apply(lambda name: name.startswith('San'))
si on remplace le « & » avec « et », il ne fonctionnera pas.
peut-être avec et à la place% est plus rapide et mantenir readibility
d'autres tests pair / impair
x est même? x% 2 == 0
x est impair? pas x% 2 == 0
est peut-être plus clair avec et 1 bit
x est impair? x & 1
x est même? pas x et 1 (impair)
def front_back(a, b):
# +++your code here+++
if not len(a) & 1 and not len(b) & 1:
return a[:(len(a)/2)] + b[:(len(b)/2)] + a[(len(a)/2):] + b[(len(b)/2):]
else:
#todo! Not yet done. :P
return