วิธีที่ดีที่สุดคือการใช้ตัวดำเนินการnot:
>>> value = True
>>> not value
False
>>> value = False
>>> not value
True
แทนรหัสของคุณ:
if bool == True:
return False
else:
return True
คุณสามารถใช้:
return not bool
การปฏิเสธตรรกะเป็นฟังก์ชัน
นอกจากนี้ยังมีสองฟังก์ชันในoperatorโมดูลoperator.not_และเป็นนามแฝงoperator.__not__ในกรณีที่คุณต้องการให้เป็นฟังก์ชันแทนที่จะเป็นตัวดำเนินการ:
>>> import operator
>>> operator.not_(False)
True
>>> operator.not_(True)
False
สิ่งเหล่านี้มีประโยชน์หากคุณต้องการใช้ฟังก์ชันที่ต้องใช้ฟังก์ชันเพรดิเคตหรือการเรียกกลับ
ตัวอย่างเช่นmapหรือfilter:
>>> lst = [True, False, True, False]
>>> list(map(operator.not_, lst))
[False, True, False, True]
>>> lst = [True, False, True, False]
>>> list(filter(operator.not_, lst))
[False, False]
แน่นอนว่าสามารถทำได้ด้วยlambdaฟังก์ชันที่เทียบเท่า:
>>> my_not_function = lambda item: not item
>>> list(map(my_not_function, lst))
[False, True, False, True]
อย่าใช้ตัวดำเนินการกลับด้านบิต~ในบูลีน
อาจถูกล่อลวงให้ใช้ตัวดำเนินการสลับบิต~หรือฟังก์ชันตัวดำเนินการที่เทียบเท่ากันoperator.inv(หรือหนึ่งในนามแฝงอื่น ๆ อีก 3 นาม) แต่เนื่องจากboolเป็นคลาสย่อยของintผลลัพธ์อาจไม่คาดคิดเนื่องจากไม่ส่งคืน "บูลีนผกผัน" จึงส่งกลับ "จำนวนเต็มผกผัน":
>>> ~True
-2
>>> ~False
-1
นั่นเป็นเพราะTrueเทียบเท่ากับ1และFalseไป0และผกผันบิตดำเนินการในการแสดงค่าที่เหมาะสมของจำนวนเต็ม และ10
ดังนั้นจึงไม่สามารถใช้ "ลบล้าง" กbool.
การลบด้วยอาร์เรย์ NumPy (และคลาสย่อย)
หากคุณกำลังจัดการกับอาร์เรย์ NumPy (หรือคลาสย่อยเช่นpandas.Seriesหรือpandas.DataFrame) ที่มีบูลีนคุณสามารถใช้ตัวดำเนินการผกผันบิต ( ~) เพื่อลบล้างบูลีนทั้งหมดในอาร์เรย์ได้:
>>> import numpy as np
>>> arr = np.array([True, False, True, False])
>>> ~arr
array([False, True, False, True])
หรือฟังก์ชัน NumPy ที่เทียบเท่า:
>>> np.bitwise_not(arr)
array([False, True, False, True])
คุณไม่สามารถใช้notโอเปอเรเตอร์หรือoperator.notฟังก์ชันบนอาร์เรย์ NumPy ได้เนื่องจากสิ่งเหล่านี้ต้องการให้สิ่งเหล่านี้ส่งคืนชุดเดียวbool(ไม่ใช่อาร์เรย์ของบูลีน) อย่างไรก็ตาม NumPy ยังมีฟังก์ชันที่ไม่ใช้ตรรกะที่ทำงานกับองค์ประกอบที่ชาญฉลาด:
>>> np.logical_not(arr)
array([False, True, False, True])
ที่สามารถนำไปใช้กับอาร์เรย์ที่ไม่ใช่บูลีน:
>>> arr = np.array([0, 1, 2, 0])
>>> np.logical_not(arr)
array([ True, False, False, True])
ปรับแต่งคลาสของคุณเอง
notทำงานโดยเรียกboolค่าและลบล้างผลลัพธ์ ในกรณีที่ง่ายที่สุดค่าความจริงจะเรียกใช้__bool__กับวัตถุ
ดังนั้นโดยการใช้งาน__bool__(หรือ__nonzero__ใน Python 2) คุณสามารถปรับแต่งค่าความจริงและผลลัพธ์ของnot:
class Test(object):
def __init__(self, value):
self._value = value
def __bool__(self):
print('__bool__ called on {!r}'.format(self))
return bool(self._value)
__nonzero__ = __bool__
def __repr__(self):
return '{self.__class__.__name__}({self._value!r})'.format(self=self)
ฉันได้เพิ่มprintคำสั่งเพื่อให้คุณสามารถตรวจสอบได้ว่ามันเรียกใช้เมธอดจริงๆ:
>>> a = Test(10)
>>> not a
__bool__ called on Test(10)
False
ในทำนองเดียวกันคุณสามารถใช้__invert__วิธีการเพื่อใช้พฤติกรรมเมื่อ~ถูกนำไปใช้:
class Test(object):
def __init__(self, value):
self._value = value
def __invert__(self):
print('__invert__ called on {!r}'.format(self))
return not self._value
def __repr__(self):
return '{self.__class__.__name__}({self._value!r})'.format(self=self)
อีกครั้งด้วยการprintโทรเพื่อดูว่าเรียกจริง:
>>> a = Test(True)
>>> ~a
__invert__ called on Test(True)
False
>>> a = Test(False)
>>> ~a
__invert__ called on Test(False)
True
อย่างไรก็ตามการใช้งาน__invert__แบบนี้อาจทำให้สับสนได้เนื่องจากพฤติกรรมของมันแตกต่างจากพฤติกรรม Python "ปกติ" หากคุณเคยทำเอกสารนั้นอย่างชัดเจนและตรวจสอบให้แน่ใจว่ามีการใช้งานที่ดี (และทั่วไป)
intและboolมีทั้งชื่อ builtin (ประเภทพวกเขาเป็นตัวแทน) และไม่ควรนำมาใช้เป็นชื่อตัวแปร