Python'da bir Boolean'ın tersini (olumsuzlamayı) nasıl elde ederim?


106

Aşağıdaki örnek için:

def fuctionName(int, bool):
    if int in range(...):
        if bool == True:
            return False
        else:
            return True

İkinci if ifadesini atlamanın herhangi bir yolu var mı? Sadece bilgisayara booleanın tersini döndürmesini söylemek için boolmi?


6
Bu muhtemelen sadece pseudocode olmakla intve bool(temsil ettikleri türleri için) hem yerleşik isimler ve değişken adı olarak kullanılmamalıdır.
SingleNegationElimination

evet, bu sadece sahte bir kod, sadece gösteri amaçlı ...
amyassin

7
if x == True:yazılmalıdır if x:.
Mike Graham

Yanıtlar:


182

Sadece kullanabilirsiniz:

return not bool

4
Ayrıca int in range (....)verimsizdir. Bir liste oluşturacak ve ardından doğrusal bir arama gerçekleştirecektir. Daha iyi x in range(low, high)olduğunu low <= x < high.
MRAB

not NoneFalse döneceğini unutmayın . En azından benim için beklediğim bu değil. Ben beklediğiniz not Noneolmak Noneöylesine notdönüş değeri olabilir bile etkisiz duruma getirmek için kullanılabilir None. Python'da uygulanma şekli, ilk önce bir boole aldığınızı doğrulamanız gerekir.
omni

56

notOperatör (mantıksal)

Muhtemelen en iyi yol operatörü kullanmaktır not:

>>> value = True
>>> not value
False

>>> value = False
>>> not value
True

Yani kodunuz yerine:

if bool == True:
    return False
else:
    return True

Kullanabilirsin:

return not bool

İşlev olarak mantıksal olumsuzlama

Orada iki işlev de vardır operatormodülü operator.not_ve 's takma operator.__not__durumda fonksiyonu olarak yerine operatör olarak ihtiyaç:

>>> import operator
>>> operator.not_(False)
True
>>> operator.not_(True)
False

Bir yüklem işlevi veya geri arama gerektiren bir işlevi kullanmak istiyorsanız, bunlar yararlı olabilir.

Örneğin mapveya 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]

Elbette aynı şey eşdeğer bir lambdaişlevle de elde edilebilir :

>>> my_not_function = lambda item: not item

>>> list(map(my_not_function, lst))
[False, True, False, True]

~Boole'lerde bitsel ters çevirme operatörünü kullanmayın

Bitsel ters çevirme operatörünü ~veya eşdeğer operatör fonksiyonunu operator.inv(veya buradaki diğer 3 takma addan birini) kullanmak cazip gelebilir . Ancak sonucun boolbir alt sınıfı olduğu intiçin beklenmedik olabilir çünkü "ters boole" döndürmez, "ters tamsayı" döndürür:

>>> ~True
-2
>>> ~False
-1

Yıllardan Bunun nedeni Trueeşdeğerdir 1ve Falsekarşı 0ve bitsel inversiyon bit cinsinden gösterimi çalışır tamsayılar 1 ve 0.

Dolayısıyla bunlar a "yadsımak" için kullanılamaz bool.

NumPy dizileriyle (ve alt sınıflarla) olumsuzluk

Eğer NumPy diziler ile ilgili (veya benzeri alt sınıfları ediyorsanız pandas.Seriesya pandas.DataFrameiçeren Boolean) aslında bitlerinin ters operatörü (kullanabilirsiniz ~etkisiz hale getirmesine) bütün bir dizideki Boolean:

>>> import numpy as np
>>> arr = np.array([True, False, True, False])
>>> ~arr
array([False,  True, False,  True])

Veya eşdeğer NumPy işlevi:

>>> np.bitwise_not(arr)
array([False,  True, False,  True])

Sen kullanamaz notoperatörü veya operator.notbunlar bu dönüş tek gerektirir çünkü NumPy diziler üzerinde fonksiyonunu bool(değil boole dizisi) Ancak NumPy da öğeye göre çalışan bir mantıklı değildir işlevi içerir:

>>> np.logical_not(arr)
array([False,  True, False,  True])

Bu, boole olmayan dizilere de uygulanabilir:

>>> arr = np.array([0, 1, 2, 0])
>>> np.logical_not(arr)
array([ True, False, False,  True])

Kendi sınıflarınızı özelleştirme

notbooldeğeri çağırarak ve sonucu olumsuzlayarak çalışır . En basit durumda, doğruluk değeri sadece __bool__nesneyi çağırır .

Dolayısıyla __bool__(veya __nonzero__Python 2'de) uygulayarak doğruluk değerini ve dolayısıyla sonucunu özelleştirebilirsiniz 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__  # Python 2 compatibility

    def __repr__(self):
        return '{self.__class__.__name__}({self._value!r})'.format(self=self)

printGerçekten yöntemi çağırdığını doğrulayabilmeniz için bir ifade ekledim :

>>> a = Test(10)
>>> not a
__bool__ called on Test(10)
False

Aynı şekilde , uygulandığında __invert__davranışı uygulamak için yöntemi de uygulayabilirsiniz ~:

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)

Yine print, aslında çağrıldığını görmek için bir telefonla:

>>> a = Test(True)
>>> ~a
__invert__ called on Test(True)
False

>>> a = Test(False)
>>> ~a
__invert__ called on Test(False)
True

Ancak __invert__böyle bir uygulama kafa karıştırıcı olabilir çünkü davranışı "normal" Python davranışından farklıdır. Bunu açıkça yaparsanız, bunu açıkça belgeleyin ve oldukça iyi (ve yaygın) bir kullanım durumu olduğundan emin olun.


11

Python'da "değil" operatörü var, değil mi? Sadece "değil" değil mi? De olduğu gibi,

  return not bool

2

Boole dizisini karşılaştırabilirsiniz. Örneğin

X = [True, False, True]

sonra

Y = X == False

sana veririm

Y = [False, True, False]

1
Bir Numpy dizisi için belki, ancak standart bir Python listesi için bu yanlıştır. OP ikisinden de bahsetmediği için bunun soruyu nasıl yanıtladığını göremiyorum.
SiHa

2

Bir geçişi uygulamaya çalışıyorsanız , kalıcı bir kodu her yeniden çalıştırdığınızda, onun reddedilmesi için, bunu aşağıdaki şekilde başarabilirsiniz:

try:
    toggle = not toggle
except NameError:
    toggle = True

Bu kodu Koşu ilk koyacaktır toggleiçin Trueve her zaman denilen bu pasajı ist, geçiş geçersiz hale gelecek.


2

Burada kabul edilen cevap, verilen senaryo için en doğru olanıdır.

Genel olarak bir boole değerini tersine çevirmek beni meraklandırdı. Görünüşe göre burada kabul edilen çözüm bir astar olarak çalışıyor ve aynı zamanda çalışan başka bir tek astar var. Bir boolean olduğunu bildiğiniz bir "n" değişkenine sahip olduğunuzu varsayarsak, onu tersine çevirmenin en kolay yolları şunlardır:

n = n is False

bu benim orijinal çözümümdü ve sonra bu sorudan kabul edilen cevap:

n = not n

İkincisi daha net, ancak performansı merak ettim ve bunu gözden geçirdim timeit- ve n = not naynı zamanda boole değerini tersine çevirmenin DAHA HIZLI yolu olduğu ortaya çıktı .


n is FalseDoğruyu test etmek için kullanmayın .
gerrit

0

Pandalar veri çerçevesi için yararlı bulduğum aynı sonucu elde etmenin başka bir yolu.

Fare ile aşağıda önerildiği gibi:

bool(1 - False)

bool(1 - True)

Neden olmasın bool(1 - False)?
fare kuyruğu

Sağ. Bu daha iyi ve daha kısa.
Candide

Pandas veri çerçevelerinin, numpy dizilerinde olduğu gibi mantıksal ters çevrilmesi yok mu?
gerrit
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.