Python ที่เทียบเท่ากับ && (ตรรกะ - และ) ในคำสั่ง if


830

นี่คือรหัสของฉัน:

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

ฉันได้รับข้อผิดพลาดในเงื่อนไขIF
ผมทำอะไรผิดหรือเปล่า?


10
เห็นได้ชัดว่าเซร์คิโออยากรู้ว่าทำไมรหัสของเขาถึงพังทลาย แต่ฉันอ่านชื่อคำถามอีกเล็กน้อย เหตุใดจะไม่ && ให้ใช้งานได้อีกต่อไป == และ! = มีอยู่ (แต่แตกต่างจากคือและไม่ใช่ฉันรู้) ทำไมไม่รวมไวยากรณ์นี้? ความชอบส่วนบุคคล?
Physicsmichael

5
@ vgm64: เพราะเหตุใดจึงมีไวยากรณ์ซ้ำซ้อนที่ไม่ได้ปรับปรุงด้านเดียว?
Konrad Rudolph

27
ฉันคิดว่าล่ามควรแทนที่จะพิมพ์ "SyntaxError: ไวยากรณ์ที่ไม่ถูกต้อง" เป็นความลับตรวจพบว่าผู้ใช้ได้ใช้&&และแนะนำให้พวกเขารู้ว่าพวกเขาอาจต้องการใช้คำหลักandแทน กันไปสำหรับสิ่งที่ต้องการ++และผู้ประกอบการทั่วไปจากภาษาอื่น ๆ
ArtOfWarfare

3
@physicsmichael "ควรมีอย่างใดอย่างหนึ่งและโดยเฉพาะอย่างยิ่งเพียงหนึ่งวิธีที่ชัดเจนในการทำ" import this
Nick T

3
@ KonradRudolph มันปรับปรุงแง่มุมของภาษาอย่างแน่นอน มันมีความสอดคล้องและใช้งานง่ายขึ้นสำหรับทุกคนที่เคยใช้ภาษาอื่นมาก่อน ความจริงที่ว่าคำถามนี้มีอยู่จริงและมีปริมาณการเข้าชมมากพอที่จะเน้นประเด็นนี้อย่างชัดเจนว่าเป็นจุดรวมทั่วไปสำหรับผู้คน
jterm

คำตอบ:


1472

คุณต้องการแทนand&&


2
สิ่งที่ฉันควรทำเพื่อสิ่งนี้: ถ้า x == 'n' และ y == 'a' หรือ y == 'b': <ทำอะไร> มันจะใช้ได้ไหม? @ChristopheD
diffracteD

7
@diffracteD: ใช้วงเล็บหากคุณต้องการแทนที่ตัวดำเนินการมาตรฐาน (ซึ่งคุณสามารถเรียนรู้เกี่ยวกับที่นี่: ibiblio.org/g2swap/byteofpython/read/operator-precedence.html )
ChristopheD

3
ฉันชอบที่เดวิด Titarencoให้ตัด n วางตัวอย่าง
Alexx Roche

7
ฉันมาถึงที่นี่หลังจากฉันพิมพ์ทั้งสอง&&และANDได้รับข้อผิดพลาด (ไม่คาดหวังว่าหลามจะต้องการคำตัวพิมพ์เล็กand)
Xeoncross

2
ฉันคิดว่าคุณควรใช้ & See: stackoverflow.com/questions/36921951/…
user1761806

229

Python ใช้andและorเงื่อนไข

กล่าวคือ

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

5
อย่าลืมว่าไพ ธ อนก็มีเช่นกัน (และ!)
inspectorG4dget

9
ตัวอย่างของคุณมีค่าเป็น "(ถ้านี่คือสิ่งนี้) หรือว่า" หรือ "ถ้าเป็นเช่นนี้และ (นี่คืออย่างนั้นหรือ)"?
Jeff

12
@ Jeff วิธีแรกของคุณ and มีลำดับความสำคัญสูงorกว่า
Buge

1
@Buge ดูเหมือนว่า "หรือ" จะสูงขึ้นมาในตารางที่คุณเชื่อมโยง
แมตต์

5
@ แก้ไขตารางจากความสำคัญต่ำสุดไปถึงสูงสุด มันง่ายกว่าที่จะจำลำดับความสำคัญถ้าคุณศึกษาพีชคณิตแบบบูล "หรือ" คือการเพิ่มและ "และ" คือการคูณ
Michael Stroud

48

ฉันได้รับข้อผิดพลาดในเงื่อนไข IF ผมทำอะไรผิดหรือเปล่า?

มีเหตุผลที่คุณได้รับSyntaxErrorคือไม่มี&&ตัวดำเนินการใน Python ในทำนองเดียวกัน||และ!มีความไม่ถูกต้องผู้ประกอบการหลาม

ตัวดำเนินการบางอย่างที่คุณอาจรู้จักจากภาษาอื่นมีชื่อแตกต่างกันใน Python ผู้ประกอบการเชิงตรรกะ&&และ||จะเรียกว่าจริงและand orในทำนองเดียวกันผู้ประกอบการปฏิเสธตรรกะที่เรียกว่า!not

ดังนั้นคุณสามารถเขียน:

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

หรือแม้กระทั่ง:

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

ข้อมูลเพิ่มเติมบางอย่าง (ที่อาจมีประโยชน์):

ฉันสรุปผู้ประกอบการ "เทียบเท่า" ในตารางนี้:

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

ดูเอกสารประกอบของ Python: 6.11 ดำเนินการบูลี

นอกจากตัวดำเนินการเชิงตรรกะ Python ยังมีตัวดำเนินการ bitwise / binary:

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

ไม่มีการปฏิเสธบิตในหลามเป็น (เพียงบิตผกผันผู้ประกอบการ~- แต่ที่ไม่เทียบเท่าnot)

ดูเพิ่มเติมที่6.6 เลขคณิต Unary และการดำเนินการระดับบิต / ไบนารีและ6.7 การดำเนินการทางเลขฐานสอง

ตัวดำเนินการเชิงตรรกะ (เหมือนในภาษาอื่น ๆ ) มีข้อได้เปรียบที่สิ่งเหล่านี้จะลัดวงจร นั่นหมายความว่าถ้าตัวถูกดำเนินการตัวแรกกำหนดผลลัพธ์ไว้ผู้ดำเนินการรายที่สองจะไม่ได้รับการประเมินเลย

เพื่อแสดงสิ่งนี้ฉันใช้ฟังก์ชั่นที่รับค่าเพียงพิมพ์และส่งคืนอีกครั้ง สิ่งนี้มีประโยชน์ในการดูสิ่งที่ประเมินผลจริงเนื่องจากข้อความสั่งพิมพ์:

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

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

อย่างที่คุณเห็นเพียงคำสั่งการพิมพ์เพียงคำสั่งเดียวดังนั้น Python จึงไม่ได้ดูตัวถูกดำเนินการที่ถูกต้องจริงๆ

นี่ไม่ใช่กรณีสำหรับตัวดำเนินการไบนารี ผู้ประเมินทั้งสองตัวถูกดำเนินการเสมอ:

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

แต่ถ้าตัวถูกดำเนินการตัวแรกนั้นไม่เพียงพอแน่นอนตัวดำเนินการที่สองจะถูกประเมิน:

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

เพื่อสรุปนี่คือตารางอื่น:

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

TrueและFalseเป็นตัวแทนของสิ่งbool(left-hand-side)ตอบแทนที่พวกเขาไม่จำเป็นต้องเป็นTrueหรือFalseพวกเขาเพียงต้องการที่จะกลับมาTrueหรือFalseเมื่อboolมีการเรียกร้องให้พวกเขา (1)

ดังนั้นใน Pseudo-Code (!) andและorฟังก์ชั่นทำงานเช่นนี้

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)

โปรดทราบว่านี่เป็นรหัสหลอกไม่ใช่รหัสงูหลาม ใน Python คุณไม่สามารถสร้างฟังก์ชั่นที่เรียกว่าandหรือorเพราะสิ่งเหล่านี้เป็นคำหลัก นอกจากนี้คุณไม่ควรใช้ "ประเมิน" if bool(...)หรือ

การปรับพฤติกรรมของชั้นเรียนของคุณเอง

นี้โดยปริยายboolโทรสามารถใช้ในการกำหนดวิธีการเรียนของคุณประพฤติด้วยand, และornot

เพื่อแสดงให้เห็นว่าสิ่งนี้สามารถปรับแต่งได้ฉันใช้คลาสนี้ซึ่งprintเป็นสิ่งที่ติดตามสิ่งที่เกิดขึ้นอีกครั้ง:

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)

ดังนั้นเรามาดูกันว่าจะเกิดอะไรขึ้นกับคลาสนั้นร่วมกับโอเปอเรเตอร์เหล่านี้:

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

ถ้าคุณไม่มี__bool__เมธอดแล้ว Python จะตรวจสอบว่าวัตถุนั้นมี__len__เมธอดหรือไม่และส่งคืนค่าที่มากกว่าศูนย์หรือไม่ อาจเป็นประโยชน์ที่จะรู้ในกรณีที่คุณสร้างคอนเทนเนอร์ตามลำดับ

ดูเพิ่มเติม4.1 ความจริงการทดสอบราคา

NumPy อาร์เรย์และคลาสย่อย

อาจจะเกินขอบเขตของคำถามเดิมเล็กน้อย แต่ในกรณีที่คุณติดต่อกับ NumPy อาร์เรย์หรือคลาสย่อย (เช่น Pandas Series หรือ DataFrames) การboolโทรโดยนัยจะเพิ่มความน่ากลัว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().

ในกรณีเหล่านี้คุณสามารถใช้ตรรกะและฟังก์ชั่นจาก NumPy ซึ่งดำเนินการองค์ประกอบที่ชาญฉลาดand(หรือ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])

หากคุณกำลังจัดการกับบูลีนอาร์เรย์คุณสามารถใช้ตัวดำเนินการไบนารีกับ NumPy สิ่งเหล่านี้ทำการเปรียบเทียบองค์ประกอบที่ฉลาด (แต่ยังเป็นไบนารี):

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

การboolเรียกใช้ตัวถูกดำเนินการต้องส่งคืนTrueหรือFalseไม่ถูกต้องอย่างสมบูรณ์ มันเป็นเพียงตัวถูกดำเนินการแรกที่ต้องการคืนค่าบูลีนด้วย__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)

นั่นเป็นเพราะandจริง ๆ แล้วคืนค่าตัวถูกดำเนินการแรกถ้าตัวถูกดำเนินการตัวแรกประเมินค่าFalseและถ้าประเมินตัวถูกTrueแล้วมันส่งคืนตัวถูกดำเนินการตัวที่สอง:

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

ในทำนองเดียวกันสำหรับorวิธีอื่น ๆ :

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

อย่างไรก็ตามหากคุณใช้พวกเขาในifคำแถลงifก็จะเรียกboolผลลัพธ์โดยปริยาย ดังนั้นคะแนนปลีกย่อยเหล่านี้อาจไม่เกี่ยวข้องกับคุณ


36

สองความคิดเห็น:

  • ใช้andและorสำหรับการดำเนินการทางตรรกะใน Python
  • ใช้ช่องว่าง 4 ช่องเพื่อเยื้องแทน 2 คุณจะขอบคุณตัวเองในภายหลังเพราะรหัสของคุณจะดูสวยมากเหมือนกับรหัสของทุกคน ดูPEP 8สำหรับรายละเอียดเพิ่มเติม

10

คุณใช้andและorเพื่อดำเนินการทางตรรกะเช่นใน C, C ++ เช่นเดียวกับตัวอักษรandเป็น&&และor||เป็น


ดูตัวอย่างความสนุกนี้

สมมติว่าคุณต้องการสร้าง Logic Gates ใน Python:

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

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

ตอนนี้ลองโทรหาพวกเขา:

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

สิ่งนี้จะออก:

False
True

หวังว่านี่จะช่วยได้!


9

ฉันไปกับการแก้ปัญหาทางคณิตศาสตร์อย่างหมดจด:

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

7
นี่ไม่ใช่คำตอบสำหรับคำถามจริง
Matthew อ่าน

5

อาจเป็นรหัสที่ดีที่สุดสำหรับงานนี้ แต่ใช้งานได้ -

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

-3

คำตอบเดียว&(ไม่เป็นสองเท่า&&) ก็เพียงพอหรือเป็นคำตอบยอดนิยมที่แนะนำให้คุณใช้ 'และ' ฉันพบสิ่งนี้ด้วยแพนด้า

cities['Is wide and has saint name'] = (cities['Population'] > 1000000) 
& cities['City name'].apply(lambda name: name.startswith('San'))

หากเราแทนที่ "&" ด้วย "และ" มันจะไม่ทำงาน


1
เดี่ยว & จะไม่ทำให้เกิดการลัดวงจรนิพจน์ (หมายถึงทั้งคู่จะถูกประเมินโดยไม่คำนึงถึงค่าส่งคืนของนิพจน์แรก)
user528025

-4

อาจจะมี & &% แทนที่เร็วกว่าและอ่านได้ง่ายกว่า

การทดสอบอื่น ๆ แม้แต่ / คี่

x คืออะไร x% 2 == 0

x แปลกไหม ไม่ใช่ x% 2 == 0

อาจจะชัดเจนมากขึ้นด้วย bitwise และ 1

x แปลกไหม x & 1

x คืออะไร ไม่ใช่ x & 1 (ไม่แปลก)

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

-4

การใช้ "และ" ในเงื่อนไข ฉันมักจะใช้สิ่งนี้เมื่อนำเข้าใน 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

14
คำถามนี้ถูกถามและตอบเกือบ 7 ปีที่ผ่านมา คำตอบของคุณเพิ่มไปยังคำตอบที่อยู่ที่นี่แล้ว? โดยทั่วไปแล้วถ้าคุณไม่มีอะไรใหม่ที่จะพูดคุณไม่ควรเพิ่มคำตอบใหม่ให้กับคำถามเก่า - ที่วัดเก่าเป็นหลายปี - เมื่อมีคำตอบที่ดีอยู่แล้ว
Jonathan Leffler
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.