“ x ไม่อยู่ใน y” หรือ“ ไม่ใช่ x ใน y”


97

เมื่อทดสอบการเป็นสมาชิกเราสามารถใช้:

x not in y

หรืออีกทางหนึ่ง:

not x in y

สามารถมีบริบทที่เป็นไปได้มากสำหรับการแสดงออกนี้ขึ้นอยู่กับและx yอาจใช้สำหรับการตรวจสอบสตริงย่อยการเป็นสมาชิกรายการการมีอยู่ของคีย์ dict เป็นต้น

  • ทั้งสองรูปแบบเทียบเท่ากันเสมอหรือไม่?
  • มีไวยากรณ์ที่ต้องการหรือไม่?

คำตอบ:


112

พวกเขามักจะให้ผลลัพธ์เดียวกัน

ในความเป็นจริงnot 'ham' in 'spam and eggs'ดูเหมือนว่าจะมีการบรรจุแบบพิเศษเพื่อดำเนินการ "ไม่อยู่ใน" รายการเดียวแทนที่จะเป็นการดำเนินการ "ใน" จากนั้นจึงปฏิเสธผลลัพธ์:

>>> 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      

ในตอนแรกฉันคิดว่าพวกเขาให้ผลลัพธ์เดียวกันเสมอ แต่notด้วยตัวมันเองนั้นเป็นเพียงตัวดำเนินการเชิงตรรกะที่มีลำดับความสำคัญต่ำซึ่งสามารถนำไปใช้กับa in bนิพจน์บูลีนอื่น ๆ ได้อย่างง่ายดายในขณะที่not inตัวดำเนินการแยกต่างหากเพื่อความสะดวกและชัดเจน .

การถอดชิ้นส่วนด้านบนเผยให้เห็น! ดูเหมือนว่าในขณะที่notเห็นได้ชัดว่าเป็นตัวดำเนินการลบเชิงตรรกะ แต่แบบฟอร์มnot a in bนี้มีการบรรจุแบบพิเศษเพื่อไม่ให้ใช้ตัวดำเนินการทั่วไป สิ่งนี้ทำให้not a in bเป็นนิพจน์เดียวกันอย่างแท้จริงa not in bแทนที่จะเป็นเพียงนิพจน์ที่ให้ผลลัพธ์เป็นค่าเดียวกัน


4
โปรดทราบว่านี่เป็นเพียงรายละเอียดการใช้งานเท่านั้น ฉันไม่พบการกล่าวถึงnot x in xsในเอกสาร
phant0m

1
@ phant0m แน่นอน; วิธีที่คุณควรจะคิดว่ามีnot x in xs not (x in xs)แต่ความจริงที่ว่ามันถูกนำมาใช้โดยการแยกวิเคราะห์ให้เป็น bytecode เดียวกันx not in xsอย่างชัดเจนแสดงให้เห็นอย่างชัดเจนว่าต้องเหมือนกันเสมอเมื่อเทียบกับสิ่งต่างๆเช่นnot x == yvs x != yซึ่งควรให้ผลลัพธ์เหมือนกัน แต่ไม่จำเป็นต้อง (ขึ้นอยู่กับการนำไปใช้งานของ__eq__และ__ne__เกี่ยวข้อง).
เบ็น

12
คุณได้ทำงานในการเพิ่มประสิทธิภาพของช่องมอง CPython ; การเพิ่มประสิทธิภาพเวลาคอมไพล์ที่การใช้งาน Python อื่น ๆ เช่น Jython และ IronPython มีอิสระที่จะเพิกเฉยหรือคัดลอก (ไม่ใช่ส่วนหนึ่งของข้อกำหนดภาษา)
Martijn Pieters

16

  1. ไม่มีไม่มีความแตกต่าง

    ผู้ประกอบการที่มีการกำหนดให้มีมูลค่าที่แท้จริงผกผันของnot inin

    - เอกสาร Python

  2. ฉันคิดว่าnot inเป็นที่ต้องการเพราะมันชัดเจนกว่าและพวกเขาเพิ่มกรณีพิเศษสำหรับมัน


8

มีความหมายเหมือนกัน แต่ตัวตรวจสอบคำแนะนำสไตล์ Python ของ pycodestyle (เดิมเรียกว่า pep8)ชอบตัวnot inดำเนินการในกฎ E713 :

E713: ควรทดสอบการเป็นสมาชิก not in

ดู"Python if x is not Noneor if not x is None?" ด้วย สำหรับการเลือกสไตล์ที่คล้ายกันมาก


3

คนอื่น ๆ ได้แสดงให้เห็นอย่างชัดเจนแล้วว่าทั้งสองงบลดลงอยู่ในระดับที่ค่อนข้างต่ำเทียบเท่ากัน

อย่างไรก็ตามฉันไม่คิดว่าจะมีใครเครียดมากพอที่จะทำให้คุณเลือกได้

เลือกแบบฟอร์มที่ทำให้โค้ดของคุณสามารถอ่านได้มากที่สุด

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


1
หากคุณทำงานเป็นทีมขนาดใหญ่หรือทำงานกับโค้ดที่มีแนวโน้มว่าจะไม่มีใครแตะต้องได้สักพักอาจมีคนอื่นดูแลรักษารหัส
Tommy Herbert


1

ในทางไวยากรณ์พวกเขาเป็นคำสั่งเดียวกัน ฉันจะรีบระบุว่า'ham' not in 'spam and eggs'สื่อถึงเจตนาที่ชัดเจนขึ้น แต่ฉันได้เห็นโค้ดและสถานการณ์ที่not 'ham' in 'spam and eggs'สื่อถึงความหมายที่ชัดเจนกว่าที่อื่น

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