Python'da 'yanlış'ı 0'a ve' doğru'u 1'e dönüştürme


120

trueTürü unicode1'e ve falsetürü unicode0'a (Python'da) dönüştürmenin bir yolu var mı ?

Örneğin: x == 'true' and type(x) == unicode

İstiyorum x = 1

Not: Kullanmak istemiyorum if- else.

Yanıtlar:


165

int()Bir boole testinde kullanın :

x = int(x == 'true')

int()booleanı 1veya değerine dönüştürür 0. Eşit olmayan herhangi bir değerin döndürülmeyle 'true'sonuçlanacağını unutmayın 0.


Bu harika bir cevaptır, ancak 'true' olmayan her şey '0' olarak yorumlanacaktır. Bunun OP'lerin gereksinimine uyup uymayacağından emin değilim.
Abhijit

Muhtemelen OP'nin istediği şey bu olsa da, python 2.7 için sorulan soruyla tam olarak eşleşmiyor. Açıkça unicode türü üzerinde çalışmasını istediler ve tür için davranışı belirtmediler str.
2013

1
@wim Aslında soru asla bir python sürümünden bahsetmez, bunun python2 olması gerektiği gerçeğini bırakın. 7 . Ayrıca python2'de u'true' == 'true'fonksiyonun girdi türünden [ strve arasında unicode] bağımsız olarak doğru şekilde davrandığına dikkat edin .
Bakuriu

Ama Bakuriu, tam olarak benim açımdan bu, "sorun" şudur u'true' == 'true've kullanım durumunun ne olduğunu bilmiyoruz. Belki bulundukları durum için farklı bir davranış istiyorlar type(x) != unicode.
2013

1
@AlbertChen: hayır, çünkü numpy dizileri karşılaştırmaları yayınlar ve bir boole değeri üretmez. Bunun yerine, karşılaştırmalar bir dizi mantıksal değer üretir . Bir arrayvalue == 'true'karşılaştırmadan ne beklediğinizden emin değilim , burada cevapladığım soru bir dizge (unicode) değerine özgü.
Martijn Pieters

137

Eğer Bbir Boole dizi, yazma olduğunu

B = B*1

(Biraz kod golfü.)


1
Bu aynı şey tek değerler için de işe yarar. Bu harika!
user31415

2
Python 3'te benim için çalışmıyor (dizi boole olarak kalıyor). Ama numpy.multiply(B,1)eserler kullanmak .
Alaa M.

bu benim için python 3'te çalışıyor! ve çok parlak bir çözüm. oh benim
alwaysaskingquestions

@Ourobours: Önerinizi takip etmeye çalışmak benim için işe yaramadı. Orijinal sulotion güzel, uygulanabilir sonuçlar B=map(int,B)verirken python 3'te benim için bir harita obejct'i döndürdü.
Eulenfuchswiesel

1
@Eulenfuchswiesel Bunun nedeni, haritanın Python3'te bir yineleyici döndürmesidir. Listeyi bir liste olarak kullanmak için, şöyle bir liste yapın: B = liste (harita (int, B))
Gigi Bayte 2

11

Boole dizinizin x.astype('uint8')nerede xolduğunu kullanabilirsiniz .


9

İşte sorununuz için başka bir çözüm:

def to_bool(s):
    return 1 - sum(map(ord, s)) % 2
    # return 1 - sum(s.encode('ascii')) % 2  # Alternative for Python 3

Bu çalıştığı için ASCII kodları toplamı 'true'DİR 448ASCII kodları toplamı ise çift sayıdır, 'false'IS 523garip oluyor.


Bu çözüm hakkında komik bir şey girişi ise onun sonucu oldukça rastgele olmasıdır değil biri 'true'veya 'false'. Zamanın yarısı geri dönecek 0ve diğer yarısı 1. Kullanılan varyant encode, giriş ASCII değilse bir kodlama hatası oluşturacaktır (dolayısıyla davranışın tanımsızlığını arttıracaktır).


Cidden, en okunabilir ve daha hızlı çözümün aşağıdakileri kullanmak olduğuna inanıyorum if:

def to_bool(s):
    return 1 if s == 'true' else 0

Bazı mikro kriterlere bakın:

In [14]: def most_readable(s):
    ...:     return 1 if s == 'true' else 0

In [15]: def int_cast(s):
    ...:     return int(s == 'true')

In [16]: def str2bool(s):
    ...:     try:
    ...:         return ['false', 'true'].index(s)
    ...:     except (ValueError, AttributeError):
    ...:         raise ValueError()

In [17]: def str2bool2(s):
    ...:     try:
    ...:         return ('false', 'true').index(s)
    ...:     except (ValueError, AttributeError):
    ...:         raise ValueError()

In [18]: def to_bool(s):
    ...:     return 1 - sum(s.encode('ascii')) % 2

In [19]: %timeit most_readable('true')
10000000 loops, best of 3: 112 ns per loop

In [20]: %timeit most_readable('false')
10000000 loops, best of 3: 109 ns per loop

In [21]: %timeit int_cast('true')
1000000 loops, best of 3: 259 ns per loop

In [22]: %timeit int_cast('false')
1000000 loops, best of 3: 262 ns per loop

In [23]: %timeit str2bool('true')
1000000 loops, best of 3: 343 ns per loop

In [24]: %timeit str2bool('false')
1000000 loops, best of 3: 325 ns per loop

In [25]: %timeit str2bool2('true')
1000000 loops, best of 3: 295 ns per loop

In [26]: %timeit str2bool2('false')
1000000 loops, best of 3: 277 ns per loop

In [27]: %timeit to_bool('true')
1000000 loops, best of 3: 607 ns per loop

In [28]: %timeit to_bool('false')
1000000 loops, best of 3: 612 ns per loop

Uyarı nasıl ifçözüm en az 2,5 kat kat daha hızlı daha tüm diğer çözümleri. Bunun bir tür ev ödevi olması dışında s'yi kullanmaktan kaçınmanın bir şartı olarak koymak mantıklı değildirif (bu durumda bunu ilk başta sormamalısınız).


7

Kendi başına bool olmayan bir dizeden genel amaçlı bir dönüşüme ihtiyacınız varsa, aşağıda gösterilene benzer bir rutin yazmanız daha iyi olur. Ördek yazmanın ruhuna uygun olarak, hatayı sessizce geçmedim, ancak mevcut senaryoya uygun şekilde dönüştürdüm.

>>> def str2bool(st):
try:
    return ['false', 'true'].index(st.lower())
except (ValueError, AttributeError):
    raise ValueError('no Valid Conversion Possible')


>>> str2bool('garbaze')

Traceback (most recent call last):
  File "<pyshell#106>", line 1, in <module>
    str2bool('garbaze')
  File "<pyshell#105>", line 5, in str2bool
    raise TypeError('no Valid COnversion Possible')
TypeError: no Valid Conversion Possible
>>> str2bool('false')
0
>>> str2bool('True')
1

2
Neden a TypeError? Eğer dize içermiyor 'true'ya 'false'da bir var değer hatası. Girdi bir dize değilse (zamanın% 99.99'u) bir dizge değilse AttributeError, bu yüzden onu yakalamak ValueErrorve yeniden yükseltmek işe yaramaz TypeError.
Bakuriu

@Bakuriu: Katılıyorum. TypeError gerçekten burada geçerli değildi.
Abhijit

@Bakuriu: Sadece meraktan dolayı index, AttributeError'ı yükseltmeye bir örnek verebilir misiniz ?
georg

@Bakuriu: Ben doğrusu aşağıya mesaja atıfta bulundu tahmin: return ['false', 'true'].index(s) except (ValueError, AttributeError).
georg

@ thg435 Bu yazıda sadece kopyalayıp yapıştırdım ve lower()aramayı kaldırmaya karar verdim çünkü bu fazladan hesaplamayı yapan tek çözüm buydu ve mikro ölçüme dahil etmek doğru olmazdı. Elbette try...exceptbiraz zaman alabilir, ancak hiçbir istisna ortaya çıkmazsa ( 20nsdaha az veya daha fazla) fark küçüktür .
Bakuriu

0

bool'dan int'e: x = (x == 'true') + 0

Şimdi x 1, eğer x == 'true'0 ise.

Not: x == 'true'0 ile eklendiğinde değeri olan int'e (bool değeri True ise 1 ise 1) tür bool döndürür.


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.