Ý nghĩa của “(1,) == 1,” trong Python là gì?


119

Tôi đang kiểm tra cấu trúc tuple và tôi thấy thật lạ khi tôi sử dụng ==toán tử như:

>>>  (1,) == 1,
Out: (False,)

Khi tôi gán hai biểu thức này cho một biến, kết quả là true:

>>> a = (1,)
>>> b = 1,
>>> a==b
Out: True

Câu hỏi này khác với quy tắc cú pháp dấu phẩy tuple trong Python theo quan điểm của tôi. Tôi hỏi nhóm các biểu thức giữa ==toán tử.


16
Nhìn vào một câu hỏi trước của OP chỉ 2 giờ trước, Có vẻ tuyệt vời (hoặc kỳ lạ) rằng cách mà chỉ cần đóng khung một câu hỏi khác nhau có thể dẫn đến kết quả khác nhau (và sự chấp nhận của cộng đồng).
AKS

24
@AKS Đây là các câu hỏi khác nhau
kmaork

7
@AKS Mặc dù các câu hỏi ở đây hơi khác một chút, nhưng tôi hoàn toàn đồng ý với quan điểm của bạn. Hiệu ứng đàn hay còn gọi là HNQ.
Mất trí

5
@PythonNewHand Thật vậy, điều đó hoàn toàn có thể chấp nhận được. Đó là lý do tại sao tôi thêm vào đó việc đóng khung một câu hỏi theo cách khác .
AKS

3
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 bạn thấy thế nào? Tôi đọc lướt những câu trả lời đó và không thấy gì có vẻ bao quát được tình huống cụ thể này.
Dan Getz

Câu trả lời:


88

Các câu trả lời khác đã cho bạn thấy rằng hành vi này là do sự ưu tiên của toán tử, như được ghi lại ở đây .

Tôi sẽ chỉ cho bạn cách tự tìm câu trả lời vào lần tới khi bạn gặp câu hỏi tương tự như thế này. Bạn có thể giải cấu trúc cách biểu thức phân tích cú pháp bằng astmô-đun:

>>> import ast
>>> source_code = '(1,) == 1,'
>>> print(ast.dump(ast.parse(source_code), annotate_fields=False))
Module([Expr(Tuple([Compare(Tuple([Num(1)], Load()), [Eq()], [Num(1)])], Load()))])

Từ điều này, chúng ta có thể thấy rằng mã được phân tích cú pháp như Tim Peters giải thích :

Module([Expr(
    Tuple([
        Compare(
            Tuple([Num(1)], Load()), 
            [Eq()], 
            [Num(1)]
        )
    ], Load())
)])

1
Một công cụ hữu ích khác là dis- Trong trường hợp này, bạn sẽ thấy hai LOAD_CONSTvới các giá trị khác nhau ( (1,)1) và một BUILD_TUPLEmã opp.
mgilson

153

Đây chỉ là ưu tiên của toán tử. Bạn trước

(1,) == 1,

nhóm như vậy:

((1,) == 1),

do đó, xây dựng một tuple với một phần tử duy nhất từ ​​kết quả của việc so sánh tuple một phần tử 1,với số nguyên 1cho bằng nhau Chúng không bằng nhau, vì vậy bạn lấy 1 tuple False,cho một kết quả.


61
Không hẳn, nhưng 1-tuples có cú pháp kỳ lạ. Nói chung, bạn muốn được nhiều ngạc nhiên nếu, ví dụ, 1+2, 2==3, 4*7đã không nhóm như (1+2), (2==3), (4*7). Trong thực tế, 1-tuples hầu như không bao giờ được sử dụng (tốt, ngoài các câu hỏi StackOverflow ;-)).
Tim Peters

6
Có lẽ "bất ngờ" sẽ là một từ tốt hơn để sử dụng hơn là "lạ". Tôi cảm thấy hơi giống như tôi đang xem một trong những bức vẽ đó có thể là hai thứ, tùy thuộc vào góc nhìn và tiêu điểm của bạn . Toán tử bình đẳng quá lớn so với dấu phẩy, thật dễ dàng để tập trung vào nó và cho rằng kết quả sẽ là True/ False. Giờ tôi đã hiểu chuyện gì đang xảy ra, điều đó hoàn toàn hiển nhiên và hợp lý.
skrrgwasme

31
Và bây giờ bạn biết "Zen của Python" có nghĩa là gì khi nói rằng một cách rõ ràng để làm điều đó "có thể không rõ ràng lúc đầu trừ khi bạn là người Hà Lan" ;-)
Tim Peters

7
Có một chút khó hiểu khi bạn đọc tài liệu và thấy rằng thứ tạo nên một bộ giá trị là dấu phẩy, không phải dấu ngoặc đơn! Vì vậy, trong câu lệnh này, dấu phẩy ở bên tay phải không được coi là một phần của bài kiểm tra mà nó được coi là dấu phân cách! Hành vi bất ngờ!
Ikra_5

3
Lời khuyên phổ biến về biểu thức là "khi nghi ngờ, hãy sử dụng dấu ngoặc đơn". Sau đó, thật tốt khi đặt các dấu ngoặc đơn xung quanh tất cả các bộ một, mặc dù chúng không phải là một phần của cú pháp tuple.
nigel222

12

Khi bạn làm

>>> (1,) == 1,

nó xây dựng một tuple với kết quả từ việc so sánh tuple (1,) với một số nguyên và do đó trả về False.

Thay vào đó, khi bạn gán cho các biến, hai bộ giá trị bằng nhau sẽ được so sánh với nhau.

Bạn co thể thử:

>>> x = 1,
>>> x
(1,)
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.