Python 2 เปรียบเทียบสตริงและ int อย่างไร เหตุใดรายการจึงเปรียบเทียบมากกว่าตัวเลขและอันดับมากกว่ารายการ


178

ตัวอย่างต่อไปนี้มีการเพิ่มความคิดเห็นด้วยเอาต์พุต ( ดังที่เห็นใน ideone.com ):

print "100" < "2"      # True
print "5" > "9"        # False

print "100" < 2        # False
print 100 < "2"        # True

print 5 > "9"          # False
print "5" > 9          # True

print [] > float('inf') # True
print () > []          # True

บางคนสามารถอธิบายได้ว่าทำไมเอาต์พุตจึงเป็นเช่นนี้?


รายละเอียดการใช้งาน

  • ลักษณะการทำงานนี้ได้รับคำสั่งจากสเป็คภาษาหรือไม่นั้นขึ้นอยู่กับผู้ใช้งานหรือไม่
  • มีความแตกต่างระหว่างการใช้งาน Python ที่สำคัญหรือไม่?
  • ภาษา Python มีความแตกต่างกันหรือไม่?

23
จากจำนวนคำถามทั้งหมด 3,000 คำถามคำถามนี้มีคำตอบอธิบายว่าทำไมภาษาจึงได้รับการออกแบบด้วยวิธีนี้ (และทำไมจึงได้รับการออกแบบใหม่ใน 3.x) นั่นไม่ใช่ส่วนหนึ่งของคำถามนี้ แต่เป็นส่วนหนึ่งของคำถามมากมายที่เชื่อมโยงที่นี่
abarnert

คำตอบ:


209

จากคู่มือpython 2 :

รายละเอียดการติดตั้ง CPython: ออบเจกต์ประเภทต่าง ๆ ยกเว้นหมายเลขจะเรียงลำดับตามชื่อประเภท วัตถุประเภทเดียวกันที่ไม่สนับสนุนการเปรียบเทียบที่เหมาะสมจะเรียงลำดับตามที่อยู่

เมื่อคุณสั่งซื้อสองสายหรือสองประเภทที่เป็นตัวเลขการเรียงลำดับจะดำเนินการตามวิธีที่คาดไว้

เมื่อคุณสั่งซื้อประเภทที่เป็นตัวเลขและไม่ใช่ตัวเลขประเภทที่เป็นตัวเลขจะมาก่อน

>>> 5 < 'foo'
True
>>> 5 < (1, 2)
True
>>> 5 < {}
True
>>> 5 < [1, 2]
True

เมื่อคุณสั่งซื้อประเภทที่เข้ากันไม่ได้สองประเภทโดยที่ไม่เป็นตัวเลขพวกเขาจะเรียงลำดับตามตัวอักษรของชื่อพิมพ์:

>>> [1, 2] > 'foo'   # 'list' < 'str' 
False
>>> (1, 2) > 'foo'   # 'tuple' > 'str'
True

>>> class Foo(object): pass
>>> class Bar(object): pass
>>> Bar() < Foo()
True

หนึ่งข้อยกเว้นคือคลาสแบบเก่าที่มักจะมาก่อนคลาสสไตล์ใหม่

>>> class Foo: pass           # old-style
>>> class Bar(object): pass   # new-style
>>> Bar() < Foo()
False

ลักษณะการทำงานนี้ได้รับคำสั่งจากสเป็คภาษาหรือไม่นั้นขึ้นอยู่กับผู้ใช้งานหรือไม่

นอกจากนี้ไม่มีสเปคภาษา การอ้างอิงภาษาพูดว่า:

มิฉะนั้นวัตถุประเภทต่าง ๆ จะเปรียบเทียบไม่เท่ากันเสมอและมีการเรียงลำดับอย่างสม่ำเสมอ แต่โดยพลการ

ดังนั้นจึงเป็นรายละเอียดการใช้งาน

มีความแตกต่างระหว่างการใช้งาน Python ที่สำคัญหรือไม่?

ฉันไม่สามารถตอบคำถามนี้ได้เพราะฉันเพิ่งใช้การติดตั้ง CPython อย่างเป็นทางการเท่านั้น แต่มีการใช้งานอื่น ๆ ของ Python เช่น PyPy

ภาษา Python มีความแตกต่างกันหรือไม่?

ใน Python 3.x พฤติกรรมมีการเปลี่ยนแปลงดังนั้นการพยายามสั่งซื้อจำนวนเต็มและสตริงจะทำให้เกิดข้อผิดพลาด:

>>> '10' > 5
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    '10' > 5
TypeError: unorderable types: str() > int()

55
เป็นเรื่องที่ดีที่พวกเขาเปลี่ยนเป็น Py3k เมื่อฉันเห็นคำถามนี้เป็นครั้งแรกความคิดของฉันคือ 'สิ่งนี้จะไม่เกิดข้อผิดพลาดหรือไม่'
JAL

9
NB ข้อยกเว้นของกฎ 2.x ที่มีการเรียงลำดับประเภทที่แตกต่างกันตามชื่อของประเภทคือวัตถุไม่มีการเปรียบเทียบจะน้อยกว่าประเภทอื่น ๆ เสมอ ใน 3.x ไม่มีการเปรียบเทียบกับประเภทอื่นจะยังคงเพิ่ม TypeError
เดฟเคอร์บี้

4
@KarelBilek: bool เป็นประเภทตัวเลข จริง == 1 ดังนั้นมันจึงไม่ใช่ <หรือ>
abarnert

3
คำสั่งย่อของชื่อประเภทของพวกเขา? คุณต้องการให้ฟีเจอร์นี้มีคุณสมบัติเมื่อใด ใครบ้างที่จะใช้สิ่งนั้น?
แจ็ค

3
ความจริงแล้วสนุก: complex(1,0) > 'abc'เป็นFalseแต่complex(1,0) > complex(0,0)เพิ่มTypeError
Eric Duminil

24

มีการเปรียบเทียบสตริงศัพท์และประเภทที่แตกต่างกันจะถูกเปรียบเทียบโดยใช้ชื่อของพวกเขา ( "int"< "string") 3.x แก้ไขจุดที่สองโดยทำให้ไม่สามารถเทียบเคียงได้


3
แต่ใน python2 int นั้นมีค่าน้อยกว่า dicts ดังนั้นมันจึงไม่สามารถพิมพ์ด้วยการพิมพ์ตามชื่อ?
Tony Suffolk 66

ฉันเพิ่งเจอคำตอบนี้และเห็นด้วยกับ Tony Suffolk วัตถุจะไม่เรียงลำดับตามชื่อประเภทเมื่อต่างกัน
Exelian

@ ประเภทตัวเลข TonySuffolk66 เป็นข้อยกเว้นของกฎนั้น NumericType ต่ำกว่าประเภทอื่นเสมอ (ยกเว้น NoneType) ใน 2.7
LEF
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.