Python’s equivalent van & amp; & amp; (logisch-en) in een dergelijke verklaring

Hier is mijn 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

Ik krijg een foutmelding in de indien voorwaardelijk.
Wat doe ik verkeerd?


1, Autoriteit 100%

u wilt andin plaats van &&.


2, Autoriteit 15%

Python gebruikt anden orvoorwaarde.

d.w.z.

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

3, Autoriteit 4%

Ik krijg een foutmelding in de indien voorwaardelijke. Wat doe ik verkeerd?

Reden dat u een SyntaxErrorkrijgt, is dat er geen &&operator in Python is. Evenzo ||en !zijn niet geldig Python operators.

Sommige van de operators die u misschien weet uit andere talen hebben een andere naam in Python.
De logische operatoren &&en ||worden eigenlijk anden orgenoemd.
Evenzo wordt de logische negatie-operator !notgenoemd.

, zodat u gewoon kunt schrijven:

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

of zelfs:

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

Enkele aanvullende informatie (die van pas kan komen):

Ik heb de operator “equivalenten” samengevat in deze tabel:

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

Zie ook Python-documentatie: 6.11. Booleaanse bewerkingen.

Naast de logische operatoren heeft Python ook bitsgewijze/binaire operatoren:

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

Er is geen bitsgewijze ontkenning in Python (alleen de bitsgewijze inverse operator ~– maar dat is nietequivalent aan not).

Zie ook 6.6. Unaire rekenkundige en bitsgewijze/binaire bewerkingenen 6.7. Binaire rekenkundige bewerkingen.

De logische operatoren (zoals in veel andere talen) hebben het voordeel dat deze worden kortgesloten.
Dat betekent dat als de eerste operand het resultaat al definieert, de tweede operator helemaal niet wordt geëvalueerd.

Om dit te laten zien, gebruik ik een functie die gewoon een waarde neemt, deze afdrukt en opnieuw retourneert. Dit is handig om te zien wat er werkelijk is
geëvalueerd vanwege de afdrukinstructies:

>>> def print_and_return(value):
...     print(value)
...     return value
>>> res = print_and_return(False) and print_and_return(True)
False

Zoals je kunt zien wordt er maar één print-statement uitgevoerd, dus Python heeft niet eens naar de juiste operand gekeken.

Dit is niet het geval voor de binaire operatoren. Die evalueren altijd beide operanden:

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

Maar als de eerste operand niet genoeg is, wordt natuurlijk de tweede operator geëvalueerd:

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

Om dit samen te vatten is hier nog een tabel:

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

De Trueen Falsevertegenwoordigen wat bool(left-hand-side)retourneert, ze hoeven niet Trueof False, ze hoeven alleen maar Trueof Falsete retourneren wanneer boolop hen wordt aangeroepen (1).

Dus in Pseudo-Code(!) werken de functies anden orals volgt:

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)

Merk op dat dit pseudo-code is en geen Python-code. In Python kun je geen functies maken met de naam andof oromdat dit trefwoorden zijn.
Gebruik ook nooit “evaluate” of if bool(...).

Het gedrag van je eigen lessen aanpassen

Deze impliciete bool-aanroep kan worden gebruikt om aan te passen hoe uw klassen zich gedragen met and, oren not.

Om te laten zien hoe dit kan worden aangepast, gebruik ik deze klasse die weer printis iets om bij te houden wat er gebeurt:

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)

Dus laten we eens kijken wat er gebeurt met die klasse in combinatie met deze operators:

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

Als u geen __bool__-methode hebt, controleert Python ook of het object een __len__-methode heeft en als deze een waarde groter dan nul retourneert.
Dat is misschien handig om te weten in het geval u een sequentieboucher maakt.

Zie ook 4.1. Waarheidswaarde testen .

Numpy-arrays en subclasses

Waarschijnlijk een beetje buiten de reikwijdte van de oorspronkelijke vraag, maar voor het geval u te maken hebt met numpy arrays of subclasses (zoals Panda’s Series of DataFrames), dan de impliciete boolCall
Zal de gevreesde 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 deze gevallen kunt u de logische en functievan NumPy gebruiken die een element-gewijs and(of or) uitvoert:

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

Als je alleen met booleaanse arrayste maken hebt, kun je ook de binaire operators gebruiken met NumPy, deze voeren element-gewijze (maar ook binaire) vergelijkingen uit:

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

Dat de bool-aanroep op de operanden Trueof Falsemoet retourneren, is niet helemaal correct. Het is gewoon de eerste operand die een boolean moet retourneren in zijn __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)

Dat komt omdat andfeitelijk de eerste operand retourneert als de eerste operand evalueert naar Falseen als het evalueert naar Truedan retourneert het de tweede operand:

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

Vergelijkbaar voor ormaar net andersom:

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

Als u ze echter gebruikt in een if-statement, roept de ifook impliciet boolaan voor het resultaat. Dus deze fijnere punten zijn misschien niet relevant voor jou.


Antwoord 4, autoriteit 2%

Twee opmerkingen:

  • Gebruik anden orvoor logische bewerkingen in Python.
  • Gebruik 4 spaties om in te springen in plaats van 2. Je zult jezelf later dankbaar zijn, want je code zal er ongeveer hetzelfde uitzien als de code van iedereen. Zie PEP 8voor meer details.

Antwoord 5

Je gebruikt anden orom logische bewerkingen uit te voeren zoals in C, C++. Zoals letterlijk andis &&en oris ||.


Bekijk dit leuke voorbeeld,

Stel dat je Logic Gates in Python wilt bouwen:

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

Probeer ze nu te bellen:

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

Dit levert het volgende op:

False
True

Hopelijk helpt dit!


Antwoord 6

Ik koos voor een puur wiskundige oplossing:

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

Antwoord 7

Waarschijnlijk is dit niet de beste code voor deze taak, maar het werkt –

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

Antwoord 8

misschien met & in plaats daarvan is % sneller en handhaaft de leesbaarheid

andere tests even/oneven

x is even ? x % 2 == 0

x is oneven ? niet x % 2 == 0

misschien is het duidelijker met bitwise en 1

x is oneven ? x & amp; 1

x is even ? niet x & amp; 1 (niet oneven)

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

Antwoord 9

Gebruik van “en” in voorwaardelijk. Ik gebruik dit vaak bij het importeren in 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

Other episodes