"X không thuộc y" hoặc "không phải x thuộc y"


97

Khi kiểm tra tư cách thành viên, chúng tôi có thể sử dụng:

x not in y

Hay cách khác:

not x in y

Có thể có nhiều ngữ cảnh cho biểu thức này tùy thuộc vào xy. Nó có thể là để kiểm tra chuỗi con, danh sách thành viên, sự tồn tại của khóa dict chẳng hạn.

  • Hai dạng có luôn luôn tương đương nhau không?
  • Có một cú pháp ưa thích không?

Câu trả lời:


112

Họ luôn đưa ra cùng một kết quả.

Trên thực tế, not 'ham' in 'spam and eggs'dường như có xu hướng đặc biệt để thực hiện một thao tác "không tham gia", chứ không phải là một thao tác "trong" và sau đó phủ định kết quả:

>>> import dis

>>> def notin():
    'ham' not in 'spam and eggs'
>>> dis.dis(notin)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE    

>>> def not_in():
    not 'ham' in 'spam and eggs'
>>> dis.dis(not_in)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE    

>>> def not__in():
    not ('ham' in 'spam and eggs')
>>> dis.dis(not__in)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        

>>> def noteq():
    not 'ham' == 'spam and eggs'
>>> dis.dis(noteq)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               2 (==)
              9 UNARY_NOT           
             10 POP_TOP             
             11 LOAD_CONST               0 (None)
             14 RETURN_VALUE      

Lúc đầu, tôi đã nghĩ rằng chúng luôn đưa ra cùng một kết quả, nhưng notbản thân nó chỉ đơn giản là một toán tử phủ định logic có mức độ ưu tiên thấp, có thể được áp dụng cho a in bdễ dàng như bất kỳ biểu thức boolean nào khác, trong khi đó not inlà một toán tử riêng biệt để thuận tiện và rõ ràng .

Sự tháo gỡ ở trên đã được tiết lộ! Có vẻ như mặc dù notrõ ràng là một toán tử phủ định logic, nhưng biểu mẫu not a in bnày được viết tắt đặc biệt để nó không thực sự sử dụng toán tử chung. Điều này làm cho not a in bbiểu thức tương tự theo nghĩa đen a not in b, thay vì chỉ là một biểu thức dẫn đến cùng một giá trị.


4
Hãy nhớ rằng đây chỉ là chi tiết triển khai. Tôi thậm chí không thể tìm thấy đề cập đến not x in xstrong tài liệu.
phant0m 23/10/12

1
@ phant0m Hoàn toàn được; cách bạn phải nghĩ ra not x in xsnot (x in xs). Nhưng thực tế là nó được thực hiện bằng cách phân tích nó vào chính xác các bytecode giống như x not in xsrất rõ ràng cho thấy rằng họ phải luôn giống nhau, như trái ngược với những thứ như not x == yvs x != ynên cung cấp cho các kết quả tương tự, nhưng không cần phải (tùy thuộc vào việc triển khai các __eq____ne__liên quan).
Ben

11
Bạn đã thực hiện tối ưu hóa lỗ nhìn trộm CPython ; tối ưu hóa thời gian biên dịch mà các triển khai Python khác như Jython và IronPython có thể bỏ qua hoặc sao chép (nó không phải là một phần của đặc tả ngôn ngữ).
Martijn Pieters

15

  1. Không, không có sự khác biệt.

    Toán tử not inđược định nghĩa để có giá trị thực ngược là in.

    - Tài liệu Python

  2. Tôi sẽ cho rằng not innó được ưu tiên hơn vì nó rõ ràng hơn và họ đã thêm một trường hợp đặc biệt cho nó.



3

Những người khác đã nói rất rõ ràng rằng hai tuyên bố, ở mức khá thấp, tương đương nhau.

Tuy nhiên, tôi không nghĩ rằng có ai đó đã đủ căng thẳng rằng vì điều này để lại sự lựa chọn cho bạn, bạn nên

chọn hình thức làm cho mã của bạn dễ đọc nhất có thể.

Và không nhất thiết là có thể đọc được càng tốt cho bất cứ ai , thậm chí nếu đó của khóa học là một điều tốt đẹp để nhằm mục đích cho. Không, chắc chắn rằng mã là như có thể đọc được càng tốt cho bạn , vì bạn là một trong những người là có khả năng nhất để trở về với mã này sau đó và cố gắng đọc nó.


Nếu bạn đang làm việc trong một nhóm lớn hoặc trên mã có khả năng không được sử dụng trong một thời gian, có nhiều khả năng người khác phải duy trì nó.
Tommy Herbert


1

Về mặt cú pháp, chúng giống nhau. Tôi sẽ nhanh chóng nói rằng 'ham' not in 'spam and eggs'truyền đạt ý định rõ ràng hơn, nhưng tôi đã thấy mã và các kịch bản trong đó not 'ham' in 'spam and eggs'truyền đạt ý nghĩa rõ ràng hơn cái khác.

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.