Làm thế nào để chuyển đổi 'false' thành 0 và 'true' thành 1 trong Python


118

Có cách nào để chuyển đổi trueloại khôngunicode thành 1 và falsekiểu unicodethành 0 (trong Python) không?

Ví dụ: x == 'true' and type(x) == unicode

tôi muốn x = 1

Tái bút: Tôi không muốn sử dụng if- else.

Câu trả lời:


164

Sử dụng int()trong thử nghiệm boolean:

x = int(x == 'true')

int()biến boolean thành 1hoặc 0. Lưu ý rằng bất kỳ giá trị nào không bằng 'true'sẽ 0được trả về.


Đây là một câu trả lời tuyệt vời ngoại trừ việc mọi thứ sans 'true' sẽ được hiểu là '0'. Không chắc liệu điều đó có phù hợp với yêu cầu OP hay không.
Abhijit

Mặc dù nó có thể là những gì OP muốn, nhưng nó không khớp chính xác với câu hỏi được yêu cầu cho python 2.7. Họ yêu cầu rõ ràng nó hoạt động trên loại unicode và không chỉ định hành vi cho loại str.
wim

1
@wim Trên thực tế, câu hỏi không bao giờ đề cập đến phiên bản python, hãy để một mình thực tế là nó phải là python2. 7 . Cũng lưu ý rằng trong python2 u'true' == 'true'vì vậy hàm hoạt động chính xác không phụ thuộc vào kiểu đầu vào [giữa strunicode].
Bakuriu

Nhưng Bakuriu, đó chính xác là quan điểm của tôi, "vấn đề" là ở chỗ đó u'true' == 'true'và chúng ta không biết trường hợp sử dụng là gì. Có thể họ muốn một hành vi khác cho tình huống type(x) != unicode.
wim

1
@AlbertChen: không, vì mảng numpy so sánh truyền phát và không tạo ra giá trị boolean. Thay vào đó, các phép so sánh tạo ra một mảng các giá trị boolean. Tôi không chắc bạn mong đợi điều gì từ một arrayvalue == 'true'so sánh, câu hỏi tôi đã trả lời ở đây dành riêng cho giá trị chuỗi (unicode).
Martijn Pieters

136

Nếu Blà một mảng Boolean, hãy viết

B = B*1

(Một đoạn mã bit golfy.)


1
Điều tương tự chính xác này cũng hoạt động cho các giá trị đơn lẻ. Điều đó thật tuyệt!
user31415

2
Không hoạt động đối với tôi trong Python 3 (mảng vẫn là boolean). Nhưng sử dụng numpy.multiply(B,1)công trình.
Alaa M.

điều này làm việc cho tôi trong python 3! và giải pháp tuyệt vời như vậy. ôi trời
luôn luôn đặt câu hỏi vào

@Ourobours: Cố gắng làm theo đề xuất của bạn không hiệu quả với tôi. Mặc dù sulotion ban đầu cho kết quả tốt, khả thi đã B=map(int,B)trả về một bản đồ bản đồ trong python 3 cho tôi.
Eulenfuchswiesel

1
@Eulenfuchswiesel Điều này là do bản đồ trả về một trình lặp trong Python3. Để sử dụng nó như một danh sách, hãy chuyển nó thành một danh sách như sau: B = list (map (int, B))
Gigi Bayte 2

11

Bạn có thể sử dụng x.astype('uint8')ở đâu xlà mảng Boolean của bạn.


9

Đây là một giải pháp khác cho vấn đề của bạn:

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

Nó hoạt động vì tổng của các mã ASCII của 'true'448, mà thậm chí, trong khi tổng các mã ASCII của 'false'523đó là số lẻ.


Điều buồn cười về giải pháp này là kết quả của nó khá ngẫu nhiên nếu đầu vào không phải là một trong 'true'hoặc 'false'. Một nửa thời gian nó sẽ quay trở lại 0, và nửa còn lại 1. Biến thể đang sử dụng encodesẽ phát sinh lỗi mã hóa nếu đầu vào không phải là ASCII (do đó làm tăng tính không xác định của hành vi).


Nghiêm túc mà nói, tôi tin rằng giải pháp dễ đọc nhất và nhanh hơn là sử dụng if:

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

Xem một số vi điểm:

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

Lưu ý rằng ifgiải pháp này nhanh hơn ít nhất 2,5 lần so với tất cả các giải pháp khác. Sẽ không hợp lý khi đặt ra yêu cầu tránh sử dụng s ngoại trừ trường hợp đây là một dạng bài tập về nhà (trong trường hợp này, bạn không nên hỏi điều này ngay từ đầu).if


7

Nếu bạn cần chuyển đổi mục đích chung từ một chuỗi mà theo đó không phải là bool, tốt hơn bạn nên viết một quy trình tương tự như quy trình được mô tả bên dưới. Để giữ đúng tinh thần gõ vịt, tôi không âm thầm sửa lỗi mà chuyển đổi sao cho phù hợp với kịch bản hiện tại.

>>> 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
Tại sao a TypeError? Nếu chuỗi không chứa 'true'hoặc 'false'đó là lỗi giá trị . Nếu đầu vào không phải là một chuỗi AttributeError, thay vào đó bạn sẽ nhận được (99,99% số lần) , do đó, việc bắt ValueErrorvà nâng lại nó là vô ích TypeError.
Bakuriu

@Bakuriu: Tôi đồng ý. TypeError thực sự không được áp dụng ở đây.
Abhijit

@Bakuriu: chỉ vì tò mò, bạn có thể cho một ví dụ về indexviệc tăng AttributeError không?
georg

@Bakuriu: Tôi đoán tôi đã thay đề cập đến bài viết của bạn dưới đây: return ['false', 'true'].index(s) except (ValueError, AttributeError).
georg

@ thg435 Trong bài đăng đó, tôi chỉ sao chép và quyết định xóa lower()cuộc gọi vì đây là giải pháp duy nhất thực hiện tính toán bổ sung này và sẽ không chính xác nếu đưa nó vào vi điểm chuẩn. Chắc chắn thậm chí try...exceptmất một chút thời gian, nhưng sự khác biệt là nhỏ nếu không có ngoại lệ nào được nêu ra (như 20nsít hơn hoặc lâu hơn).
Bakuriu

0

bool thành int: x = (x == 'true') + 0

Bây giờ x chứa 1 nếu x == 'true' khác 0.

Lưu ý: x == 'true'sẽ trả về bool mà sau đó sẽ được đánh dấu thành int có giá trị (1 nếu giá trị bool là True khác 0) khi được thêm với 0.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.