φυβλαςのβλογ
บล็อกของ phyblas



เกร็ดเล็กน้อยเรื่อง and และ or ในภาษา python
เขียนเมื่อ 2019/06/24 11:50
เวลาใช้ if ในภาษาไพธอน บ่อยครั้งที่เราจะใช้ and และ or เพื่อรวมเงื่อนไข ๒​ ข้อขึ้นไปเข้าด้วยกัน

หลักการโดยพื้นฐานอธิบายไว้ใน https://phyblas.hinaboshi.com/tsuchinoko06

แต่มีรายละเอียดเพิ่มเติมเล็กๆน้อยๆเกี่ยวกับการใช้ and และ or ที่ไม่ได้กล่าวถึงในนั้น และหลายคนอาจจะยังไม่รู้ จึงขอเขียนถึงไว้ในหน้านี้



ลำดับก่อนหลังนั้นสำคัญ

ในการใช้งานโดยทั่วไปบางคนอาจไม่ได้ใส่ใจลำดับก่อนหลัง เพราะผลลัพท์ที่ได้ยังไงก็เหมือนกัน เช่น
a = 3
b = 5
if(a>4 or b>4):
    print('มีตัวที่มากกว่า 4')

แบบนี้จะสลับเป็น b>4 or a>4 ก็ได้ผลไม่ต่างกัน อย่างไรก็ตาม จริงๆแล้วการทำงานที่เกิดขึ้นภายในนั้นต่างกัน

ที่จริงแล้วเมื่อมีการใช้ and หรือ or จะมีการพิจารณาความจริงเท็จไล่จากตัวซ้ายก่อน ถ้าผลจริงเท็จถูกตัดสินไปแล้ว ตัวทางขวาจะไม่ถูกนำมาคิดแล้ว

หมายความว่าถ้าใช้ or แล้วพบว่าตัวซ้ายเป็นจริง ยังไงทั้งหมดก็เป็นจริงแน่นอนแล้วไม่ว่าตัวขวาจะเป็นอะไร จึงไม่มีการคิดทางขวาต่อ ถ้าทางขวาเป็นฟังก์ชันก็จะไม่มีการทำงานเกิดขึ้น

และถ้าเป็น and แล้วตัวซ้ายเป็นเท็จ แบบนี้ต่อให้ตัวขวาเป็นอย่างไรผลก็เป็นเท็จแน่นอนแล้วจึงไม่มีการทำอะไรกับตัวขวาต่อ

เพื่อให้เห็นภาพชัด ลองสมมุติฟังก์ชันง่ายๆที่จะมีการ print อะไรทุกครั้งที่มีการเรียกใช้ ก่อนที่จะคืนค่าออกมา
def f(x):
    if(x%3==0):
        print('x=%d หาร 3 ลงตัว'%x)
    else:
        print('x=%d หาร 3 ไม่ลงตัว'%x)
    return x%3==0

if(f(x=5) or f(x=6)):
    print('มี x ที่หาร 3 ลงตัว')

ได้
x=5 หาร 3 ไม่ลงตัว
x=6 หาร 3 ลงตัว
มี x ที่หาร 3 ลงตัว

แต่หากเปลี่ยนเป็น

if(f(x=6) or f(x=5)):
    print('มี x ที่หาร 3 ลงตัว')

จะได้
x=6 หาร 3 ลงตัว
มี x ที่หาร 3 ลงตัว

นั่นคือเมื่อพบว่าตัวแรกคือ x=6 นั้นหาร 3 ลงตัวดีแล้ว ตัวทางขวาคือ x=5 ก็ไม่ถูกนำมาคิดอีก ซึ่งจะเห็นได้ว่าไม่มีการ print กรณี x=5 ออกมา

จะเรียงกันกี่ตัวก็ได้ ถ้าเจอสักตัวที่เป็นจริงก็จะหยุดทันที
if(f(x=7) or f(x=8) or f(x=9) or f(x=10)):
    print('มี x ที่หาร 3 ลงตัว')


จะได้ว่าหยุดหลังเจอ x=9
x=7 หาร 3 ไม่ลงตัว
x=8 หาร 3 ไม่ลงตัว
x=9 หาร 3 ลงตัว
มี x ที่หาร 3 ลงตัว

ในทางกลับกัน ถ้าใช้ and แล้วเจอตัวที่เป็นเท็จเมื่อไหร่ก็จะหยุดทันที
if(f(x=6) and f(x=5) and f(x=4)):
    print('ทุกตัวหาร 3 ลงตัว')
else:
    print('มีตัวที่หาร 3 ไม่ลงตัว')

ได้
x=6 หาร 3 ลงตัว
x=5 หาร 3 ไม่ลงตัว
มีตัวที่หาร 3 ไม่ลงตัว

หากเราใส่ใจแค่ผลลัพท์สุดท้าย ก็อาจจะไม่ต้องใส่ใจเรื่องลำดับว่าจะวางอะไรไว้ซ้ายหรือขวาก็ได้

แต่หากสิ่งที่อยู่ในนั้นเป็นฟังก์ชันที่มีการทำอะไรบางอย่างข้างในไปด้วยนอกเหนือจากแค่คืนค่า อาจส่งผลอะไรบางอย่างที่ต่างกันได้ จึงต้องระวัง

และอีกเรื่องหนึ่งคือ มันอาจส่งผลถึงเวลาที่ถูกใช้ในการคำนวณของโปรแกรม

อย่าง สมมุติเรามีเงื่อนไขหลายอย่าง แล้วต้องการให้ถ้าเป็นจริงแค่เงื่อนไขใดหนึ่งก็พอแล้ว แบบนี้ควรเอาเงื่อนไขที่คำนวณได้เร็วไว้ก่อน ส่วนเงื่อนไขที่คำนวณช้าเอาไว้ทีหลัง

เช่น สมมุติว่า x เป็นเลขตัวนึง และ lis เป็นลิสต์อะไรสักอย่างที่บรรจุตัวเลขไว้มากมาย
if(x==0 or x in lis):

การดูว่า x เท่ากับ 0 หรือไม่นั้นใช้เวลาน้อยกว่าการดูว่า x เป็นสมาชิกในลิสต์หรือเปล่ามาก ดังนั้นให้ x==0 ไว้ทางซ้ายน่าจะดีกว่า

หรือลองยกตัวอย่างที่เทียบกับชีวิตจริง เช่นเรากำลังสงสัยว่าคอมเสียหรือไม่ ถ้าเสียจะส่งไปให้ช่างคอมซ่อม

สมมุติว่าการตรวจว่า cpu เสียหรือเปล่าใช้เวลาน้อยกว่า ram และการตรวจ gpu ใช้เวลานานที่สุด งั้นเราก็ควรจะตรวจ cpu ก่อน แล้วตามด้วย ram
if(cpu_เสียหรือ(คอม) or ram_เสียหรือ(คอม) or gpu_เสียหรือ(คอม)):
    ส่งไปให้ช่างซ่อม(คอม)
else:
    เปิดคอมเล่นเกม(คอม)



and และ or ไม่ต้องใช้แค่กับ if

แม้กรณีส่วนใหญ่จะใช้กับ if แต่บางครั้งก็เจอในสถานการณ์อื่น

เช่นถ้าจะแค่ใช้ให้หาค่าเก็บไว้ในตัวแปร หรือว่าจะ print ออกมาเลยก็ได้
a = 2
x = (a>3 or a<1)
print(x) # ได้ False
print(a<3 and a>1) # ได้ True

กรณีแบบนี้ or อาจคล้ายกับการใช้ | ส่วน and คล้ายกับการใช้ & เพียงแต่ and และ or มีลำดับความสำคัญสูงกว่า จึงไม่ต้องใส่วงเล็บ แต่ | และ & ต้องใส่
x = ((a>3) | (a<1))
print(x) # ได้ False
print((a<3) & (a>1)) # ได้ True


ผลของ and และ or ไม่ได้มีแต่ True และ False

ถ้าใช้ and จะได้ค่าตัวซ้ายสุดที่มีค่าความจริงเป็นเท็จ (เช่น False, None, 0 หรือลิสต์ว่าง) แต่หากไม่มีที่เป็นเท็จเลยจะให้ค่าตัวขวาสุด

ตัวอย่าง
print(0 and False and None) # ได้ 0
print(1 and 0 and False and None) # ได้ 0
print(False and [] and 0) # ได้ False
print(1 and None and 0) # ได้ None
print(1 and 2 and 3 and 0) # ได้ 0
print(1 and 2 and 3) # ได้ 3
print(1 and 3 and 2) # ได้ 2

ถ้าเป็น or จะได้ค่าตัวซ้ายสุดที่มีค่าความจริงเป็นจริง แต่ถ้าไม่มีที่เป็นจริงเลยจะได้ตัวขวาสุด

print(0 or 1 or 2) # ได้ 1
print(0 or 2 or 1) # ได้ 2
print([] or None or 0) # ได้ 0
print([] or 0 or None) # ได้ None

นี่เป็นหลักการทำงานโดยละเอียดจริงๆของ and และ or



ใช้ and หรือ or แทน if ได้

จากคุณสมบัติที่ว่ามา บางครั้งก็อาจนำมาใช้แทน if ได้ เช่น

เนื่องจาก and จะทำตัวทางขวาต่อเมื่อตัวทางซ้ายเป็นจริง ดังนั้นหากเขียนแบบนี้
x>1 and print("x มากกว่า 1")

แบบนี้มีค่าเท่ากับ
if(x>1): print("x มากกว่า 1")

ส่วน or จะทำตัวทางขวาต่อเมื่อทางซ้ายเป็นเท็จ ดังนั้นหากเขียนแบบนี้
x>3 or print("x ไม่มากกว่า 3")

จะเท่ากับเขียนว่า
if(not x>3): print("x ไม่มากกว่า 3")

อย่างไรก็ตาม เมื่อพิจารณาเรื่องความง่ายในการเข้าใจแล้ว โอกาสที่จะเขียนแบบนี้อาจมีไม่มากนัก เพราะเข้าใจยากกว่าการใช้ if ธรรมดา แม้อาจทำให้การเขียนดูสั้นลงก็ตาม


-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> python

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
python
-- numpy
-- matplotlib

-- pandas
-- pytorch
maya
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
javascript
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
-- บันทึกในฮ่องกง
-- บันทึกในมาเก๊า
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
เรียนภาษาจีน
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  ค้นหาบทความ

  บทความแนะนำ

เรียนรู้วิธีการใช้ regular expression (regex)
หลักการเขียนทับศัพท์ภาษาจีนกวางตุ้ง
การใช้ unix shell เบื้องต้น ใน linux และ mac
หลักการเขียนทับศัพท์ภาษาจีนกลาง
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
บันทึกการเที่ยวสวีเดน 1-12 พ.ค. 2014
แนะนำองค์การวิจัยและพัฒนาการสำรวจอวกาศญี่ปุ่น (JAXA)
เล่าประสบการณ์ค่ายอบรมวิชาการทางดาราศาสตร์โดยโซวเคนได 10 - 16 พ.ย. 2013
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
บันทึกการเที่ยวญี่ปุ่นครั้งแรกในชีวิต - ทุกอย่างเริ่มต้นที่สนามบินนานาชาติคันไซ
หลักการเขียนทับศัพท์ภาษาญี่ปุ่น
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ
ทำไมถึงอยากมาเรียนต่อนอก
เหตุผลอะไรที่ต้องใช้ภาษาวิบัติ?

ไทย

日本語

中文