False == 0 ve True == 1 bir uygulama detayı mı yoksa dil tarafından garanti ediliyor mu?


245

O garantisi var False == 0ve True == 1Python (kullanıcı tarafından yeniden olmadığını varsayarak)? Örneğin, Python'un sürümü ne olursa olsun (hem mevcut hem de muhtemelen gelecekteki olanlar) aşağıdaki kodun her zaman aynı sonuçları üreteceği garanti edilir mi?

0 == False  # True
1 == True   # True
['zero', 'one'][False]  # is 'zero'

Resmi belgelere yapılan göndermeler çok takdir edilecektir!

Düzenleme : Birçok boolcevapta belirtildiği gibi, kaynağını devralır int. "Belgelerine resmen o programcılar, tamsayılar devralan boolelerde güvenebilirsiniz söylüyor mu: Soru nedenle olarak yeniden dökülebilir değerlerle 0ve1 ?". Bu soru, uygulama ayrıntıları nedeniyle başarısız olmayacak sağlam kod yazma ile ilgilidir!


63
@ S.Lott: Yukarıdaki soruyu sormak için birçok neden var. Bu nedenle, boolean'lara güvenmenin tamsayı olmasının kodunuzu basitleştirdiği durumlar vardır: değiştirmek zorunda mısınız? Veya, başkaları tarafından yazılan ve booleların tamsayı olmasına dayanan bir koddaki yerleri tespit edebilirsiniz: mevcut kodu "düzeltmek" için kodda değiştirdiğiniz şeyi kesintiye uğratır mısınız veya mevcut kodlamanın sağlam olduğundan emin olabilir misiniz? ? Başka örneklerin bolluğu var. Daha genel olarak, oyunun kurallarını bilmek iyidir, böylece iyi oynayabilir ve sağlam bir şekilde programlayabilirsiniz.
Eric O Lebigot

10
@ S.Lott: Orijinal gönderi noktanızı tam olarak yansıtıyor: soru aslında "Bu bir uygulama detayı mı?", Çünkü bir kişinin uygulama detaylarına bağlı olmaması gerektiği fikrine tamamen katılıyorum. Boolelar resmi olarak bilinen değerlerin tamsayılarıysa, söz konusu kod uygulama ayrıntılarına dayanmaz, bu da iyidir.
Eric O Lebigot

5
@S. Lot: False == 0 ve True == 1'in bir sıradaki kaç boolun doğru olduğunu saymayı kolaylaştırır: Sadece yazabilirsiniz sum(bool_list). Aksi takdirde yazmanız gerekir sum(1 for x bool_list if x).
dan04

8
@dan: Booleans saymanın bir yolu bu. Bunun bool_list.count(True)daha açık olduğunu söyleyebilirim ; Ayrıca 3 kat daha hızlı… :)
Eric O Lebigot

2
cevaplar gösterdiği gibi @akonsu, Python boolean olan aslında tamsayılar (belirli bir alt sınıfı). Ayrıca, Python açıkça sahip türleri; belki "statik olarak yazılmamış" demek istediniz? Ayrıca, "Kodda hata yapmazdım" ile ne demek istediğinizden emin değilim. Artık, booleanları tamsayılarla karıştırmayı sevmiyorum, çünkü kavramsal olarak farklılar ve Python booleans'in tamsayı olup olmadığını umursamıyorum, ancak 0 ve 1 değerleriyle bunların yararlı olduğunu bilmiyorum.
Eric O Lebigot

Yanıtlar:


184

Python 2.x sürümünde bu, yeniden atanabileceği ve yeniden atanabileceği için garanti edilmez . Ancak, bu olsa bile, boolean True ve boolean False, karşılaştırmalar için hala düzgün bir şekilde döndürülür.TrueFalse

Python 3.x ise Trueve Falseanahtar kelimeler ve her zaman eşit olacaktır 1ve 0.

Normal koşullarda Python 2'de ve her zaman Python 3'te:

Falsenesne, boolbir alt sınıf olan türdedir int:

object
   |
 int
   |
 bool

Örneğinizde çalışmanın tek nedeni budur ['zero', 'one'][False]. Tamsayı alt sınıfı olmayan bir nesne ile çalışmaz, çünkü liste indeksleme sadece tamsayılarla veya bir __index__yöntemi tanımlayan nesnelerle çalışır (teşekkürler mark-dickinson ).

Düzenle:

Geçerli python sürümü ve Python 3 sürümü için geçerlidir. Python 2.6 için belgeler ve Python 3 için belgeler şunları söylüyor:

İki tür tamsayı vardır: [...] Tamsayılar (int) [...] Booleans (bool)

ve boolean alt bölümünde:

Booleans: Bunlar False ve True doğruluk değerlerini temsil eder [...] Boolean değerleri hemen hemen tüm bağlamlarda sırasıyla 0 ve 1 değerleri gibi davranır, istisna bir dizeye dönüştürüldüğünde "False" veya "True" dizeleridir "sırasıyla döndürülür.

Ayrıca, Python 2 için :

Sayısal bağlamlarda (örneğin, aritmetik bir işleç için argüman olarak kullanıldığında), bunlar [False and True] sırasıyla 0 ve 1 tamsayıları gibi davranırlar.

Bu nedenle, booleans açıkça Python 2.6 ve 3'te tamsayı olarak kabul edilir.

Yani Python 4 gelene kadar güvendesiniz. ;-)


2
0 == 0.0 ['sıfır', 'bir'] [0.0] başarısız olurken True değerini döndürür. ['zero', 'one'] [False] çalışır çünkü bool int'nin bir alt sınıfıdır. (int .__ subclasses __ () döndürür [<type 'bool'>])
luc

20
Nitpick: __index__yöntem sağlayan herhangi bir nesne bir liste dizini olarak kullanılabilir; intya da sadece alt sınıfları değil long.
Mark Dickinson

Ah evet, orada da. Ancak Python 3.0 belgelerine bağlantı vermemek daha iyi olur: 3.0 öldü. :)
Mark Dickinson

4
Re: "Python 2.x içinde bu doğru ve yanlış yeniden atanması mümkün olduğu için garanti edilmez". IMHO, bu doğru olsa da, Doğru veya Yanlış yeniden atanan herkes, elde ettikleri garip sonuçları hak ediyor. Özellikle, yeniden atamadan önce True depolamak ve ardından yeniden atamadan sonra sonucu True ile karşılaştırmak kırılır. a = True; True = 'i am an idiot'; a == True=> Yanlış. Bu tür yeniden atama dışında, varsayılan değerler 0 ve 1 olarak standartlaştırılmıştır ve buna bağlı olarak yaygın bir uygulama olduğuna inanıyorum; örneğin, iki öğeli bir dizine indekslemek için, burada [0] yanlış durumu, [1] true değerini tutar.
ToolmakerSteve

True'nun pratikte 1 ve False 0 gibi kabul edilebileceği konusunda başka bir resmi teyit fark ettim: docs.python.org/2/library/stdtypes.html#boolean-values . Bunu bu cevaba ekliyorum.
Eric O Lebigot

78

Python 2.3'teki yeni bool tipini tartışan PEP bağlantısı: http://www.python.org/dev/peps/pep-0285/ .

Bir bool'u int'e dönüştürürken, tamsayı değeri her zaman 0 veya 1'dir, ancak int'i bir boole dönüştürürken, boolean değeri 0 dışındaki tüm tamsayılar için True'dur.

>>> int(False)
0
>>> int(True)
1
>>> bool(5)
True
>>> bool(-5)
True
>>> bool(0)
False

22

Python 2.x'te hiç garanti edilmez:

>>> False = 5
>>> 0 == False
False

Böylece değişebilir. Python 3.x'te True, False ve None ayrılmış sözcüklerdir , bu nedenle yukarıdaki kod çalışmaz.

Genel olarak, booleans ile False değerinin her zaman 0 tamsayı olmasına rağmen (yukarıdaki gibi değiştirmediğiniz sürece) True'nun başka bir değere sahip olabileceğini varsaymalısınız. Mutlaka herhangi bir garantiye güvenmem True==1, ancak Python 3.x'te, ne olursa olsun, her zaman böyle olacak.


3
Re "True başka bir değer olabilir. Ben mutlaka True == 1 herhangi bir garanti güvenmek olmaz." Aslında, python.org/dev/peps/pep-0285 uyarınca True == 1'e güvenebilirsiniz ve spec docs.python.org/2/reference/… "Boole değerleri 0 ve 1 değerleri gibi davranır , neredeyse tüm bağlamlarda ... "Doğru veya Yanlış'ı yeniden atayarak Py 2'de bunu geçersiz kılmanın imkansız olduğunu söylemiyorum, ancak projenizdeki bazı programcılar aptal değilse ve böyle bir yeniden atama yapmazlarsa, davranış garantilidir.
ToolmakerSteve

-2

Çok basit. Bool, bir tamsayıyı bir bool olarak değerlendirmeyle ilgili olduğundan, SADECE sıfır yanlış bir cevap verir. TÜM Sıfır olmayan değerler, kayan noktalar, negatif sayılar dahil tamsayılar veya neyin var, doğru döndürür.

Bunun neden yararlı olduğuna dair güzel bir örnek, bir cihazın güç durumunu belirlemektir. Açık sıfır olmayan bir değerdir, kapalı sıfırdır. Elektronik konuşma bu anlamlıdır.

Değerler arasında göreceli olarak doğru veya yanlış belirlemek için, onu karşılaştıracağınız bir şey olmalıdır. Bu kullanarak, dizeleri ve sayı değerler için geçerlidir ==ya !=ya <, > >=, <=vb

Bir değişkene bir tamsayı atayabilir ve daha sonra bu değişken değerine dayalı olarak doğru veya yanlış alabilirsiniz.


1
Soru True == 1'in tamsayıların boolean değeriyle değil Python tarafından garanti edilip edilmediğiyle ilgilidir.
Eric O Lebigot

-3

Sadece yazın int(False)ve alırsınız 0, yazarsanız int(True)çıktı alırsınız1


4
Bu sadece False ve True'nun int()basit bir sayısal anlamla 0 ve 1 ile tam olarak aynı olmadığı için geçerli girdiler olduğu anlamına gelir.
Eric O Lebigot 10:18

-5

Yanlış bir bool. Farklı bir türü vardır. Bir tamsayı olan 0'dan farklı bir nesnedir.

0 == FalseFalse bir tam sayıya çevrildiğinden True değerini döndürür. int (False) 0 döndürür

== operatörünün python belgeleri diyor (yardım ('==')):

Operatörler <, >, ==, >=, <=, ve !=iki nesne değerlerini karşılaştırın. Nesnelerin aynı tipte olması gerekmez. Her ikisi de sayı ise, ortak bir türe dönüştürülür.

Sonuç olarak False, karşılaştırma ihtiyacı için bir tamsayıya dönüştürülür. Ama 0'dan farklı.

>>> 0 is False
False

26
Bu tam olarak doğru değil boolbir alt sınıfıdır intyüzden çok gerçek anlamda bir bool, olan bir tamsayı. Örneğin, isinstance(True, int)True değerini döndürür. Eşitlik kontrolü, bool'u int'e dönüştürmez, çünkü dönüştürme gerekli değildir: int.__cmp__doğrudan arar . Bunun bool.__cmp__ is int.__cmp__da değerlendirildiğini unutmayın True.
Mark Dickinson

3
Bu cevap için -1. Bool ve int arasındaki ilişkinin yanlış açıklaması (Python 2'de). isinstance(True, int)=> Doğru. Yani, True IS bir tamsayıdır ve dönüşüm gerektirmez.
ToolmakerSteve

False veya Int döndüren bir senaryo vardı ... kullanarak while response is Falseçalıştı ve while response == Falseolmadı .. Teşekkürler!
curly_brackets

5
Bu 0 is Falseyanlış bir şey söylemez. İnteraktif tercüman olarak, girmek x = -10, daha sonra y = -10, daha sonra x is yo edeceğiz de yanlış. Python yorumlayıcısının belirli durumlarda aynı tamsayı nesnelerini yeniden kullandığı optimizasyonlar olması (tamsayı değişmezlerini sabitler olarak saklamak, küçük tamsayıları birleştirmek) istamsayı değer eşitliğini test etmek istediğinizde kullanılması gerektiği anlamına gelmez .
Martijn Pieters
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.