Python 2 so sánh chuỗi và int như thế nào? Tại sao danh sách so sánh lớn hơn số và bộ dữ liệu lớn hơn danh sách?


178

Đoạn mã sau được chú thích với đầu ra ( như đã thấy trên 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

Ai đó có thể giải thích tại sao đầu ra là như vậy?


Chi tiết thực hiện

  • Là hành vi này được ủy quyền bởi đặc tả ngôn ngữ, hoặc là tùy thuộc vào người thực hiện?
  • Có sự khác biệt giữa bất kỳ triển khai Python chính nào không?
  • Có sự khác biệt giữa các phiên bản của ngôn ngữ Python?

23
Trong số 3000 câu hỏi của câu hỏi này, câu hỏi này có câu trả lời giải thích tại sao ngôn ngữ được thiết kế theo cách này (và tại sao nó được thiết kế lại trong 3.x). Đó không phải là một phần của câu hỏi này, nhưng là một phần của nhiều câu hỏi được liên kết ở đây.
abarnert

Câu trả lời:


209

Từ hướng dẫn sử dụng python 2 :

Chi tiết triển khai CPython: Các đối tượng thuộc các loại khác nhau ngoại trừ số được sắp xếp theo tên loại của chúng; các đối tượng cùng loại không hỗ trợ so sánh thích hợp được sắp xếp theo địa chỉ của chúng.

Khi bạn đặt hàng hai chuỗi hoặc hai loại số, việc sắp xếp được thực hiện theo cách mong đợi (thứ tự từ điển cho chuỗi, thứ tự số cho số nguyên).

Khi bạn đặt một loại số và một loại không số, loại số đến trước.

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

Khi bạn đặt hàng hai loại không tương thích trong đó không phải là số, chúng được sắp xếp theo thứ tự chữ cái của các kiểu chữ của chúng:

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

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

Một ngoại lệ là các lớp kiểu cũ luôn xuất hiện trước các lớp kiểu mới.

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

Là hành vi này được ủy quyền bởi đặc tả ngôn ngữ, hoặc là tùy thuộc vào người thực hiện?

Không có đặc điểm kỹ thuật ngôn ngữ . Tài liệu tham khảo ngôn ngữ nói:

Mặt khác, các đối tượng thuộc các loại khác nhau luôn so sánh không bằng nhau và được sắp xếp một cách nhất quán nhưng tùy ý.

Vì vậy, nó là một chi tiết thực hiện.

Có sự khác biệt giữa bất kỳ triển khai Python chính nào không?

Tôi không thể trả lời câu hỏi này vì tôi chỉ sử dụng triển khai CPython chính thức, nhưng có những triển khai khác của Python như PyPy.

Có sự khác biệt giữa các phiên bản của ngôn ngữ Python?

Trong Python 3.x hành vi đã được thay đổi để cố gắng đặt hàng một số nguyên và một chuỗi sẽ phát sinh lỗi:

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

55
Thật tốt khi họ đã thay đổi nó trong Py3k. Khi tôi lần đầu tiên nhìn thấy câu hỏi này, suy nghĩ của tôi là 'cái gì, điều này không gây ra lỗi?'.
JAL

9
NB Một ngoại lệ đối với quy tắc 2.x rằng các loại khác nhau được sắp xếp theo tên của loại đó là đối tượng Không có luôn so sánh ít hơn mọi loại khác. Trong 3.x so sánh Không có loại nào khác sẽ vẫn tăng TypeError.
Dave Kirby

4
@KarelBilek: bool là một kiểu số. Và True == 1 vì vậy nó cũng không <nor>.
abarnert

3
Thứ tự từ điển của tên loại của họ? Khi nào bạn muốn đây là một tính năng? Ai sẽ sử dụng nó?
Jack

3
Sự thật thú vị: complex(1,0) > 'abc'Falsenhưng complex(1,0) > complex(0,0)tăng mộtTypeError
Eric Duminil

24

Các chuỗi được so sánh theo từ vựng và các loại khác nhau được so sánh theo tên của loại của chúng ( "int"< "string"). 3.x sửa điểm thứ hai bằng cách làm cho chúng không thể so sánh được.


3
Nhưng trong python2 int's ít hơn dicts nên nó không thể chỉ là từ vựng theo tên loại?
Tony Suffolk 66

Tôi chỉ bắt gặp câu trả lời này và đồng ý với Tony Suffolk. Các đối tượng KHÔNG được sắp xếp theo tên loại khi không giống nhau.
Exelian

@ Kiểu số TonySuffolk66 là ngoại lệ cho quy tắc đó. NumericType luôn thấp hơn bất kỳ loại nào khác (ngoại trừ noneType) trong 2.7.
lef
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.