1090 Stimmen

Pythons Äquivalent von && (logisch-und) in einer if-Anweisung

Das klappt nicht:

if cond1 && cond2:

1868voto

ChristopheD Punkte 106139

Utilice and 代わりに && .

286voto

David Titarenco Punkte 31667

Python verwendet and y or Konditionale.

d.h.

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

110voto

MSeifert Punkte 131411

Ich erhalte einen Fehler in der IF-Bedingung. Was mache ich falsch?

Das ist der Grund, warum Sie eine SyntaxError ist, dass es keine && Operator in Python. Ebenso || y ! son nicht gültig Python-Operatoren.

Einige der Operatoren, die Sie vielleicht aus anderen Sprachen kennen, haben in Python einen anderen Namen. Die logischen Operatoren && y || werden eigentlich als and y or . Ebenso ist der logische Negationsoperator ! heißt not .

Sie könnten also einfach schreiben:

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

oder sogar:

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

Einige zusätzliche Informationen (die sich als nützlich erweisen könnten):

Ich habe die "Äquivalente" der Betreiber in dieser Tabelle zusammengefasst:

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

Siehe auch Python-Dokumentation: 6.11. Boolesche Operationen .

Neben den logischen Operatoren verfügt Python auch über bitweise/binäre Operatoren:

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

In Python gibt es keine bitweise Negation (nur den bitweisen Umkehroperator ~ - aber das ist no gleichbedeutend mit not ).

Siehe auch 6.6. Unäre Arithmetik und bitweise/binäre Operationen y 6.7. Binäre arithmetische Operationen .

Die logischen Operatoren haben (wie in vielen anderen Sprachen) den Vorteil, dass sie kurzgeschlossen sind. Das heißt, wenn der erste Operand bereits das Ergebnis definiert, dann wird der zweite Operator gar nicht ausgewertet.

Um dies zu zeigen, verwende ich eine Funktion, die einfach einen Wert nimmt, ihn ausgibt und wieder zurückgibt. Dies ist praktisch, um zu sehen, was tatsächlich ausgewertet wird aufgrund der Druckanweisungen ausgewertet wird:

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

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

Wie Sie sehen, wird nur eine Druckanweisung ausgeführt, so dass Python den rechten Operanden gar nicht beachtet hat.

Dies ist bei den binären Operatoren nicht der Fall. Diese werten immer beide Operanden aus:

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

Aber wenn der erste Operand nicht ausreicht, wird natürlich der zweite Operator ausgewertet:

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

Um dies zusammenzufassen, hier eine weitere Tabelle:

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

El True y False darstellen, was bool(left-hand-side) Renditen, müssen sie nicht sein True o False sie müssen nur zurückkehren True o False wenn bool angerufen wird (1).

In Pseudo-Code(!) wird also die and y or Funktionen funktionieren wie folgt:

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)

Beachten Sie, dass es sich hierbei um Pseudocode und nicht um Python-Code handelt. In Python können Sie keine Funktionen namens and o or denn dies sind Schlüsselwörter. Außerdem sollten Sie niemals "bewerten" oder if bool(...) .

Anpassen des Verhaltens der eigenen Klassen

Diese implizite bool Aufruf kann verwendet werden, um das Verhalten Ihrer Klassen mit and , or y not .

Um zu zeigen, wie dies angepasst werden kann, verwende ich diese Klasse, die wiederum print s etwas, um zu verfolgen, was vor sich geht:

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)

Schauen wir uns also an, was mit dieser Klasse in Kombination mit diesen Operatoren passiert:

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

Wenn Sie keine __bool__ Methode prüft Python auch, ob das Objekt eine __len__ Methode und wenn sie einen Wert größer als Null zurückgibt. Dies könnte nützlich sein, wenn Sie einen Sequenzcontainer erstellen.

Siehe auch 4.1. Wahrheitswertprüfung .

NumPy-Arrays und Unterklassen

Wahrscheinlich ein bisschen über den Rahmen der ursprünglichen Frage, aber für den Fall, dass Sie mit NumPy Arrays oder Unterklassen (wie Pandas Serie oder DataFrames) dann die implizite bool aufrufen wird die gefürchtete 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().

In diesen Fällen können Sie die logischen und Funktion von NumPy, die eine elementweise and (oder 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])

Wenn Sie sich nur mit boolesche Arrays Sie könnten auch die binären Operatoren mit NumPy verwenden, diese führen elementweise (aber auch binäre) Vergleiche durch:

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

Dass die bool Aufruf auf die Operanden muss zurückgeben True o False ist nicht ganz korrekt. Es ist nur der erste Operand, der einen booleschen Wert in seinem __bool__ Methode:

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)

Das liegt daran, dass and gibt tatsächlich den ersten Operanden zurück, wenn der erste Operand den Wert False und wenn es sich als True dann gibt es den zweiten Operanden zurück:

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

Ähnliches gilt für or sondern genau andersherum:

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

Wenn Sie sie jedoch in einem if Anweisung der if wird auch implizit aufrufen bool über das Ergebnis. Diese Feinheiten sind für Sie also möglicherweise nicht relevant.

42voto

istruble Punkte 12793

Zwei Bemerkungen:

  • Utilice and y or für logische Operationen in Python.
  • Verwenden Sie 4 Leerzeichen zum Einrücken anstelle von 2. Sie werden sich später bedanken, denn Ihr Code wird so ziemlich genauso aussehen wie der aller anderen. Siehe PEP 8 für weitere Einzelheiten.

14voto

Big Red Punkte 153

Ich habe mich für eine rein mathematische Lösung entschieden:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X