False == 0 และ True == 1 รายละเอียดการใช้งานหรือรับประกันด้วยภาษาหรือไม่


245

มันรับประกันหรือไม่False == 0และTrue == 1ใน Python (สมมติว่าผู้ใช้ไม่ได้กำหนดใหม่)? ตัวอย่างเช่นมีการรับประกันว่ารหัสต่อไปนี้จะให้ผลลัพธ์ที่เหมือนกันไม่ว่าจะเป็น Python รุ่นใด (ทั้งที่มีอยู่และที่เป็นไปได้ในอนาคต)

0 == False  # True
1 == True   # True
['zero', 'one'][False]  # is 'zero'

การอ้างอิงถึงเอกสารอย่างเป็นทางการจะได้รับการชื่นชมมาก!

แก้ไข : ตามที่ระบุไว้ในคำตอบหลายสืบทอดจากbool intคำถามนี้สามารถสร้างใหม่เป็น: "เอกสารอย่างเป็นทางการกล่าวว่าโปรแกรมเมอร์สามารถพึ่งพาบูลีนที่สืบทอดมาจากจำนวนเต็มพร้อมค่า0และ1 ?" คำถามนี้เกี่ยวข้องกับการเขียนโค้ดที่มีประสิทธิภาพซึ่งจะไม่ล้มเหลวเนื่องจากรายละเอียดการใช้งาน!


63
@ S.Lott: มีหลายเหตุผลที่จะถามคำถามข้างต้น ดังนั้นมีบางครั้งที่การพึ่งพา booleans เป็นจำนวนเต็มทำให้รหัสของคุณง่ายขึ้น: คุณต้องเปลี่ยนมันหรือไม่? หรือคุณอาจพบสถานที่ในโค้ดที่เขียนโดยบุคคลอื่นที่อาศัย booleans เป็นจำนวนเต็ม: คุณขัดจังหวะสิ่งที่คุณกำลังแก้ไขในรหัสเพื่อ "แก้ไข" รหัสที่มีอยู่หรือคุณสามารถมั่นใจได้ว่าการเข้ารหัสปัจจุบันเป็นเสียง ? มีตัวอย่างอื่นอีกมากมาย โดยทั่วไปแล้วมันเป็นการดีที่จะรู้กฎของเกมเพื่อให้คุณสามารถเล่นได้ดีและตั้งโปรแกรมในลักษณะที่ดี
Eric O Lebigot

10
@ S.Lott: โพสต์ต้นฉบับสะท้อนถึงจุดของคุณอย่างแม่นยำ: คำถามคือ "นี่คือรายละเอียดการดำเนินการหรือไม่" เพราะฉันเห็นด้วยกับคุณอย่างเต็มที่ในความคิดที่ว่าไม่ควรขึ้นอยู่กับรายละเอียดการใช้งาน หากบูลีนเป็นจำนวนเต็มอย่างเป็นทางการของค่าที่รู้จักกันแล้วรหัสในคำถามไม่พึ่งพารายละเอียดการใช้งานซึ่งเป็นสิ่งที่ดี
Eric O Lebigot

5
@S ล็อต: รู้ว่าเป็นเท็จ == 0 และจริง == 1 ทำให้ง่ายต่อการนับจำนวนบูลในลำดับที่เป็นจริง: คุณสามารถเขียนsum(bool_list)ได้ sum(1 for x bool_list if x)มิฉะนั้นคุณจะต้องเขียน
dan04

8
@ ด่าน: นั่นเป็นวิธีหนึ่งในการนับบูลีน ฉันจะบอกว่าbool_list.count(True)ชัดเจนมากขึ้น ก็ยังประมาณ 3 ครั้งได้เร็วขึ้น ... :)
เอริคโอ Lebigot

2
@akonsu ตามคำตอบที่แสดง Python booleans เป็นจำนวนเต็ม (คลาสย่อยเฉพาะของ) ยิ่งกว่านั้นงูหลามก็มีประเภท; บางทีคุณอาจหมายถึงว่ามันเป็น "ไม่พิมพ์แบบคงที่"? นอกจากนี้ฉันไม่แน่ใจว่าคุณหมายถึงอะไรโดย "ฉันจะไม่ทำผิดพลาดในรหัส" ตอนนี้ฉันไม่ชอบผสม booleans กับจำนวนเต็มเพราะพวกเขามีแนวคิดที่แตกต่างกันและฉันจะไม่รังเกียจถ้า Python booleans ไม่ได้เป็นจำนวนเต็ม แต่รู้ว่าพวกเขามีค่า 0 และ 1 มีประโยชน์
Eric O Lebigot

คำตอบ:


184

ใน Python 2.x สิ่งนี้ไม่รับประกันว่าจะเป็นไปได้TrueและFalseจะถูกกำหนดใหม่ อย่างไรก็ตามแม้ว่าสิ่งนี้จะเกิดขึ้นบูลีนจริงและบูลีนเท็จก็ยังคงกลับมาอย่างถูกต้องสำหรับการเปรียบเทียบ

ในหลาม 3.x TrueและFalseเป็นคำหลักและมักจะเท่ากับและ10

ภายใต้สถานการณ์ปกติใน Python 2 และเสมอใน Python 3:

Falseวัตถุเป็นประเภทboolซึ่งเป็น subclass ของint:

object
   |
 int
   |
 bool

มันเป็นเหตุผลเดียวที่ทำไมในตัวอย่างของคุณ['zero', 'one'][False]ใช้งานได้ มันจะไม่ทำงานกับวัตถุที่ไม่ใช่ subclass ของจำนวนเต็มเนื่องจากการทำดัชนีรายการใช้ได้กับจำนวนเต็มหรือวัตถุที่กำหนด__index__วิธีการ (ขอบคุณmark-dickinson )

แก้ไข:

เป็นจริงของเวอร์ชัน python ปัจจุบันและของ Python 3 เอกสารสำหรับ python 2.6และdocs สำหรับ Python 3ทั้งคู่บอกว่า:

มีจำนวนเต็มสองประเภท: [... ] จำนวนเต็ม (int) [... ] Booleans (bool)

และในส่วนย่อยบูลีน:

Booleans: สิ่งเหล่านี้แสดงถึงค่าความจริงเท็จและจริง [... ] ค่าบูลีนจะทำงานเหมือนค่า 0 และ 1 ตามลำดับในบริบทเกือบทั้งหมดยกเว้นว่าเมื่อถูกแปลงเป็นสตริงสตริง "เท็จ" หรือ "จริง" "จะถูกส่งกลับตามลำดับ

นอกจากนี้สำหรับ Python 2 :

ในบริบทตัวเลข (ตัวอย่างเช่นเมื่อใช้เป็นอาร์กิวเมนต์ให้กับตัวดำเนินการทางคณิตศาสตร์) พวกเขา [เท็จและจริง] ทำตัวเหมือนจำนวนเต็ม 0 และ 1 ตามลำดับ

ดังนั้นบูลีนจึงถูกพิจารณาอย่างชัดเจนว่าเป็นจำนวนเต็มใน Python 2.6 และ 3

ดังนั้นคุณจะปลอดภัยจนกว่า Python 4 จะมาพร้อมกัน ;-)


2
0 == 0.0 คืนค่า True เมื่อ ['ศูนย์', 'หนึ่ง'] [0.0] ล้มเหลว ['ศูนย์', 'หนึ่ง'] [เท็จ] ใช้ได้เพราะบูลเป็นคลาสย่อยของ int (int .__ subclasses __ () ส่งคืน [<type 'bool'>])
luc

20
Nitpick: วัตถุใด ๆ ที่ให้__index__วิธีการนั้นสามารถใช้เป็นรายการดัชนีได้ ไม่ได้เป็นเพียงคลาสย่อยหรือint long
Mark Dickinson

อ่าใช่มันอยู่ที่นั่นด้วย แต่จะเป็นการดีกว่าถ้าไม่เชื่อมโยงกับเอกสาร Python 3.0: 3.0 ตาย :)
Mark Dickinson

4
Re: "ใน Python 2.x สิ่งนี้ไม่สามารถรับประกันได้เพราะเป็นไปได้ที่ True และ False จะถูกกำหนดใหม่" IMHO ในขณะที่สิ่งนี้เป็นจริงทุกคนที่มอบหมายจริงหรือเท็จสมควรได้รับผลกระทบที่แปลกประหลาดอะไรก็ตามที่พวกเขาได้รับ การจัดเก็บ True ก่อนการมอบหมายใหม่จากนั้นเปรียบเทียบผลลัพธ์กับ True หลังจากการมอบหมายใหม่จะแตก a = True; True = 'i am an idiot'; a == True=> เท็จ นอกเหนือจากการกำหนดใหม่ค่าเริ่มต้นจะได้มาตรฐานเป็น 0 และ 1 และฉันเชื่อว่าเป็นเรื่องปกติที่ต้องพึ่งพาสิ่งนั้น เช่นการจัดทำดัชนีเป็นอาร์เรย์สององค์ประกอบโดยที่ [0] ถือเป็นกรณีเท็จ [1] จริง
ToolmakerSteve

ผมเพิ่งสังเกตเห็นอีกยืนยันอย่างเป็นทางการจากข้อเท็จจริงที่ว่าสามารถที่แท้จริงในทางปฏิบัติได้รับการพิจารณาเช่น 1 และเท็จ 0: docs.python.org/2/library/stdtypes.html#boolean-values ฉันกำลังเพิ่มเข้ากับคำตอบนี้
Eric O Lebigot

78

เชื่อมโยงไปยัง PEP คุยประเภทบูลใหม่ในหลาม 2.3: http://www.python.org/dev/peps/pep-0285/

เมื่อแปลง bool เป็น int ค่าจำนวนเต็มจะเป็น 0 หรือ 1 เสมอ แต่เมื่อแปลง int เป็น bool ค่าบูลีนจะเป็น True สำหรับจำนวนเต็มทั้งหมดยกเว้น 0

>>> int(False)
0
>>> int(True)
1
>>> bool(5)
True
>>> bool(-5)
True
>>> bool(0)
False

22

ใน Python 2.x จะไม่รับประกันเลย:

>>> False = 5
>>> 0 == False
False

ดังนั้นมันสามารถเปลี่ยนแปลงได้ ใน Python 3.x, True, False และ None เป็นคำสงวนดังนั้นโค้ดด้านบนจะไม่ทำงาน

โดยทั่วไปแล้วด้วย booleans คุณควรสมมติว่าในขณะที่ False จะมีค่าจำนวนเต็มเป็น 0 เสมอ (ตราบใดที่คุณไม่เปลี่ยนแปลงดังที่กล่าวมาข้างต้น) True อาจมีค่าอื่น ฉันไม่จำเป็นต้องพึ่งพาการรับประกันใด ๆTrue==1แต่ใน Python 3.x นี่จะเป็นกรณีเสมอไม่ว่าจะเกิดอะไรขึ้น


3
เรื่อง "True สามารถมีค่าอื่น ๆ ได้ฉันไม่จำเป็นต้องพึ่งพาการรับประกันใด ๆ ว่า True == 1" ที่จริงแล้วคุณสามารถพึ่งพา True == 1 ตามpython.org/dev/peps/pep-0285และ spec docs.python.org/2/reference/ … "ค่าบูลีนจะทำงานเหมือนค่า 0 และ 1 ตามลำดับ ในบริบทเกือบทั้งหมด ... "ฉันไม่ได้บอกว่ามันเป็นไปไม่ได้ที่จะแทนที่สิ่งนี้ใน Py 2 โดยการมอบหมายจริงหรือเท็จใหม่ แต่ฉันกำลังบอกว่าถ้าโปรแกรมเมอร์บางคนในโครงการของคุณเป็นคนงี่เง่าและมอบหมายใหม่เช่นนั้น รับประกันพฤติกรรม
ToolmakerSteve

-2

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

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

ในการกำหนดความจริงหรือเท็จค่อนข้างระหว่างค่าคุณต้องมีสิ่งที่จะเปรียบเทียบ นี้นำไปใช้สตริงและค่าจำนวนการใช้==หรือ!=หรือ<, > >=, <=ฯลฯ

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


1
คำถามเกี่ยวกับว่า True == 1 รับประกันโดย Python หรือไม่ไม่ใช่เกี่ยวกับค่าบูลีนของจำนวนเต็ม
Eric O Lebigot

-3

เพียงแค่เขียนint(False)และคุณจะได้รับ0ถ้าคุณพิมพ์int(True)มันจะออก1


4
นี่หมายความว่า False และ True เป็นอินพุตที่ถูกต้องint()ซึ่งมีความหมายเชิงตัวเลขอย่างง่ายไม่ใช่ว่าเหมือนกันกับ 0 และ 1
Eric O Lebigot

-5

เท็จเป็นบูล มันมีประเภทที่แตกต่างกัน มันเป็นวัตถุที่แตกต่างจาก 0 ซึ่งเป็นจำนวนเต็ม

0 == Falseผลตอบแทนจริงเพราะเท็จถูกโยนเป็นจำนวนเต็ม int (เท็จ) ผลตอบแทน 0

เอกสารไพ ธ อนของโอเปอเรเตอร์ == พูดว่า (ความช่วยเหลือ ('==')):

ผู้ประกอบการ<, >, ==, >=, <=และ!=เปรียบเทียบค่าของวัตถุสอง วัตถุไม่จำเป็นต้องมีชนิดเดียวกัน หากทั้งคู่เป็นตัวเลขพวกมันจะถูกแปลงเป็นประเภททั่วไป

ดังนั้น False จะถูกแปลงเป็นจำนวนเต็มสำหรับความต้องการของการเปรียบเทียบ แต่มันแตกต่างจาก 0

>>> 0 is False
False

26
สิ่งนี้ไม่ถูกต้อง: boolเป็นคลาสย่อยของintดังนั้นในความเป็นจริงบูลเป็นจำนวนเต็ม ตัวอย่างเช่นisinstance(True, int)ส่งคืน True และการตรวจสอบความเท่าเทียมกันไม่ได้แปลงบูลเป็น int เนื่องจากไม่จำเป็นต้องทำการแปลงมันเพียงแค่เรียกint.__cmp__โดยตรง โปรดทราบว่ายังประเมินbool.__cmp__ is int.__cmp__ True
Mark Dickinson

3
-1 สำหรับคำตอบนี้ คำอธิบายที่ไม่ถูกต้องของความสัมพันธ์ระหว่างบูลและ int (ใน Python 2) isinstance(True, int)=> จริง นั่นคือ True ISเป็นจำนวนเต็มและไม่ต้องการการแปลง
ToolmakerSteve

ฉันมีสคริปต์ที่ส่งคืน False หรือ Int ... โดยใช้while response is Falseงานได้และwhile response == Falseไม่ได้ .. ขอบคุณ!
curly_brackets

5
นั่น0 is Falseคือเท็จบอกอะไรคุณ ในล่ามโต้ตอบของคุณใส่x = -10แล้วy = -10แล้วx is yและจะยังเป็นเท็จ เพียงเพราะมีการเพิ่มประสิทธิภาพในที่ที่ล่าม Python ใช้วัตถุจำนวนเต็มเดียวกันอีกครั้งในบางสถานการณ์ (การจัดเก็บตัวอักษรจำนวนเต็มเป็นค่าคงที่การใช้จำนวนเต็มขนาดเล็ก) ไม่ได้หมายความว่าisควรใช้เมื่อคุณต้องการทดสอบความเท่าเทียมกันของค่าจำนวนเต็ม
Martijn Pieters
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.