Bagaimana mengubah 'false' menjadi 0 dan 'true' menjadi 1 dengan Python

118

Apakah ada cara untuk mengubah truetipe unicodemenjadi 1 dan falsetipe unicodemenjadi 0 (dengan Python)?

Sebagai contoh: x == 'true' and type(x) == unicode

saya ingin x = 1

PS: Saya tidak ingin menggunakan if- else.

PythonEnthusiast
sumber

Jawaban:

164

Gunakan int()pada uji boolean:

x = int(x == 'true')

int()mengubah boolean menjadi 1atau 0. Perhatikan bahwa nilai apa pun yang tidak sama dengan 'true'akan 0dikembalikan.

Martijn Pieters
sumber
Ini adalah jawaban yang luar biasa kecuali bahwa semua tanpa 'true' akan ditafsirkan sebagai '0'. Tidak yakin apakah itu sesuai dengan persyaratan OP.
Abhijit
Meskipun mungkin itu yang diinginkan OP, itu tidak sama persis dengan pertanyaan yang diminta untuk python 2.7. Mereka secara eksplisit memintanya untuk bekerja pada tipe unicode dan tidak menentukan perilaku untuk tipe str.
wim
1
@wim Sebenarnya pertanyaannya tidak pernah menyebutkan versi python, apalagi seharusnya python2. 7 . Perhatikan juga bahwa di python2 u'true' == 'true'sehingga fungsi berperilaku dengan benar secara independen dari tipe input [antara strdan unicode].
Bakuriu
Tapi Bakuriu, itulah maksud saya, "masalahnya" adalah itu u'true' == 'true'dan kita tidak tahu apa use case-nya. Mungkin mereka menginginkan perilaku yang berbeda untuk situasi dimana type(x) != unicode.
wim
1
@AlbertChen: tidak, karena numpy array menyiarkan perbandingan dan tidak menghasilkan nilai boolean. Sebaliknya, perbandingan menghasilkan larik nilai boolean. Saya tidak yakin apa yang Anda harapkan dari arrayvalue == 'true'perbandingan, pertanyaan yang saya jawab di sini khusus untuk nilai string (unicode).
Martijn Pieters
136

Jika Badalah array Boolean, tulis

B = B*1

(Sedikit kode golf.)

Snoop Catt
sumber
1
Hal yang sama persis juga berlaku untuk nilai tunggal. Ini bagus!
pengguna31415
2
Tidak berfungsi untuk saya dengan Python 3 (array tetap boolean). Tapi menggunakan numpy.multiply(B,1)karya.
Alaa M.
ini bekerja untuk saya di python 3! dan solusi yang brilian. oh my
alwaysaskingquestions
@Ourobours: Mencoba mengikuti saran Anda tidak berhasil untuk saya. Sementara sulotion asli memberikan hasil yang bagus dan bisa diterapkan B=map(int,B)mengembalikan peta obejct di python 3 untuk saya.
Eulenfuchswiesel
1
@Eulenfuchswiesel Ini karena map mengembalikan iterator dengan Python3. Untuk menggunakannya sebagai daftar, masukkan sebagai daftar seperti ini: B = list (map (int, B))
Gigi Bayte 2
11

Anda dapat menggunakan x.astype('uint8')where xis your Boolean array.

shahar_m
sumber
9

Inilah solusi lain untuk masalah Anda:

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

Ia bekerja karena jumlah dari kode ASCII dari 'true'yaitu 448, yang bahkan, sedangkan jumlah dari kode ASCII dari 'false'yaitu 523yang aneh.


Hal yang lucu tentang solusi ini adalah hasilnya cukup acak jika inputnya bukan salah satu 'true'atau 'false'. Separuh waktu akan kembali 0, dan separuh lainnya 1. Varian yang menggunakan encodeakan memunculkan kesalahan encoding jika inputnya bukan ASCII (sehingga meningkatkan perilaku yang tidak ditentukan).


Serius, saya yakin solusi yang paling mudah dibaca dan lebih cepat adalah dengan menggunakan if:

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

Lihat beberapa microbenchmark:

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

Perhatikan bagaimana ifsolusinya setidaknya 2,5x kali lebih cepat dari semua solusi lainnya. Ini tidak masuk akal untuk menempatkan sebagai syarat untuk menghindari penggunaan ifs kecuali jika ini adalah beberapa jenis pekerjaan rumah (dalam hal ini Anda tidak harus meminta ini di tempat pertama).

Bakuriu
sumber
7

Jika Anda memerlukan konversi tujuan umum dari string yang sebenarnya bukan bool, sebaiknya Anda menulis rutinitas yang serupa dengan yang digambarkan di bawah ini. Sesuai dengan semangat mengetik bebek, saya tidak melewati kesalahan tersebut secara diam-diam, tetapi mengubahnya sesuai dengan skenario saat ini.

>>> 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
Abhijit
sumber
2
Mengapa a TypeError? Jika string tidak mengandung 'true'atau 'false'itu adalah kesalahan nilai . Jika inputnya bukan string, Anda akan mendapatkan (99,99% dari waktu) an AttributeError, maka tidak ada gunanya menangkap ValueErrordan menaikkannya kembali sebagai TypeError.
Bakuriu
@ Bakuriu: Saya setuju. TypeError memang tidak berlaku di sini.
Abhijit
@ Bakuriu: hanya karena ingin tahu, dapatkah Anda memberikan contoh indexcara meningkatkan AttributeError?
georg
@Bakuriu: Saya kira saya agak mengacu posting Anda di bawah ini: return ['false', 'true'].index(s) except (ValueError, AttributeError).
georg
@ thg435 Dalam posting itu saya baru saja menyalin-tempel dan memutuskan untuk menghapus lower()panggilan karena ini adalah satu-satunya solusi yang melakukan perhitungan tambahan ini dan tidak akan benar untuk memasukkannya ke dalam tolok ukur mikro. Memang sih try...exceptmemakan waktu agak lama, tapi bedanya kecil kalau tidak terkecuali dinaikkan (seperti 20nskurang atau lebih).
Bakuriu
0

bool ke int: x = (x == 'true') + 0

Sekarang x berisi 1 jika x == 'true'lagi 0.

Catatan: x == 'true'akan mengembalikan bool yang kemudian akan diketik menjadi int yang memiliki nilai (1 jika nilai bool adalah True else 0) bila ditambahkan 0.

MC Akash
sumber
-2

hanya dengan ini:

const a = true; const b = salah;

console.log (+ a); // 1 console.log (+ b); // 0

Fernando Pascoal Gomes
sumber