2010-08-14 41 views
35

tôi đã nhận thấy rằng cả hai làm việc như nhau:Nếu vòng lặp: "x không" và "không x trong"

if x not in listif not x in list.

Có sự khác biệt nào giữa hai trường hợp trong một số trường hợp nhất định không? Có lý do gì để có cả hai, hay chỉ vì nó tự nhiên hơn đối với một số người để viết cái này hay cái kia?

Tôi có nhiều khả năng thấy mã nào trong mã của người khác?

+0

Hoàn toàn có thể chấp nhận để đóng câu hỏi cũ hơn là bản sao của câu hỏi mới hơn. Xem http: //meta.stackoverflow.com/q/255410, http://meta.stackexchange.com/a/147651 – ThisSuitIsBlackNot

Trả lời

50

Hai hình thức làm bytecode giống hệt nhau, như bạn có thể xác minh rõ ràng:

>>> import dis 
>>> dis.dis(compile('if x not in d: pass', '', 'exec')) 
    1   0 LOAD_NAME    0 (x) 
       3 LOAD_NAME    1 (d) 
       6 COMPARE_OP    7 (not in) 
       9 JUMP_IF_FALSE   4 (to 16) 
      12 POP_TOP    
      13 JUMP_FORWARD    1 (to 17) 
     >> 16 POP_TOP    
     >> 17 LOAD_CONST    0 (None) 
      20 RETURN_VALUE   
>>> dis.dis(compile('if not x in d: pass', '', 'exec')) 
    1   0 LOAD_NAME    0 (x) 
       3 LOAD_NAME    1 (d) 
       6 COMPARE_OP    7 (not in) 
       9 JUMP_IF_FALSE   4 (to 16) 
      12 POP_TOP    
      13 JUMP_FORWARD    1 (to 17) 
     >> 16 POP_TOP    
     >> 17 LOAD_CONST    0 (None) 
      20 RETURN_VALUE   

nên rõ ràng là họ đang ngữ nghĩa giống hệt nhau.

Như một vấn đề về phong cách, PEP 8 không đề cập đến vấn đề.

Cá nhân, tôi rất thích hình thức if x not in y - làm cho nó ngay lập tức rõ ràng rằng not in là một toán tử đơn lẻ, "đọc như tiếng Anh". if not x in y có thể đánh lừa một số độc giả nghĩ rằng nó có nghĩa là if (not x) in y, đọc một chút ít như tiếng Anh, và hoàn toàn không có lợi thế bù.

1

Nó chỉ là sở thích cá nhân. Bạn cũng có thể so sánh if x != 3if not x == 3. Không có sự khác biệt giữa hai biểu thức bạn đã hiển thị.

+10

Chúng không giống nhau. '! =' calls '__ne__' và' == 'gọi' __eq__'. Trong trường hợp ngược, các ví dụ của bạn có thể có kết quả khác nhau –

+1

Đúng vậy. Tôi đáng lẽ phải thêm vào, "đảo ngược sang một bên"! –

4

not x in L không được phép rõ ràng vì điều đó sẽ ngớ ngẩn. x not in L được cho phép rõ ràng (mặc dù nó biên dịch sang cùng một bytecode) vì nó dễ đọc hơn.

x not in L là những gì mọi người sử dụng.

3

Khi bạn viết a not in b, sử dụng toán tử not in, trong khi not a in b sử dụng toán tử in và sau đó phủ nhận kết quả. Nhưng toán tử not in được xác định để trả về giống như not a in b để chúng thực hiện chính xác điều tương tự. Từ số documentation:

Các toán tử innot in kiểm tra thành viên thu nợ. x in s đánh giá là đúng nếu x là thành viên của bộ sưu tập s và sai khác. x not in s trả về phủ định của x in s.

Tương tự, có a is not b so với not a is b.

Cú pháp bổ sung được thêm vào vì nó giúp người đọc dễ dàng hơn một cách tự nhiên.

+1

Phần lạ là khi bạn sử dụng mô-đun 'dis', nó cho thấy rằng cả hai đều so sánh bằng cách sử dụng' không in' bất chấp những gì các tài liệu nói ... – avacariu

6
>>> dis.dis(lambda: a not in b) 
1   0 LOAD_GLOBAL    0 (a) 
      3 LOAD_GLOBAL    1 (b) 
      6 COMPARE_OP    7 (not in) 
      9 RETURN_VALUE  

>>> dis.dis(lambda: not a in b) 
1   0 LOAD_GLOBAL    0 (a) 
      3 LOAD_GLOBAL    1 (b) 
      6 COMPARE_OP    7 (not in) 
      9 RETURN_VALUE 

khi bạn làm "không phải là một trong b" nó sẽ cần phải được chuyển đổi cho (không in)

như vậy, đúng cách là "một không b".

Các vấn đề liên quan