Как преобразовать false в 0 и true в 1 в Python


121

Есть ли способ преобразовать trueтип unicodeв 1 и falseтип unicodeв 0 (в Python)?

Например: x == 'true' and type(x) == unicode

я хочу x = 1

PS: Я не хочу использовать if- else.

Ответы:


165

Используйте int()в булевом тесте:

x = int(x == 'true')

int()превращает логическое значение в 1или 0. Обратите внимание, что любое значение, не равное, 'true'будет 0возвращено.


Это замечательный ответ, за исключением того, что все без «истины» будет интерпретировано как «0». Не уверен, что это подойдет для требований OP.
Abhijit

Хотя это, вероятно, то, что хотел OP, это не совсем соответствует вопросу, заданному для python 2.7. Они явно попросили, чтобы он работал с типом unicode, и не указали поведение для типа str.
wim

1
@wim На самом деле вопрос никогда не упоминает версии python, не говоря уже о том, что это должен быть python2. 7 . Также обратите внимание, что в python2 u'true' == 'true'функция ведет себя правильно независимо от типа ввода [между strи unicode].
Bakuriu

Но Бакуриу, это именно моя точка зрения, «проблема» в том, u'true' == 'true'что мы не знаем, каков вариант использования. Может быть, они хотят другого поведения в той ситуации, когда type(x) != unicode.
wim

1
@AlbertChen: нет, потому что numpy массивы транслируют сравнения и не производят логическое значение. Вместо этого сравнения производят массив логических значений. Я не уверен, что вы ожидаете от arrayvalue == 'true'сравнения, вопрос, на который я здесь ответил, относится к строковому (unicode) значению.
Мартейн Питерс

137

Если Bэто логический массив, напишите

B = B*1

(Немного кода гольфиста.)


1
То же самое работает и для отдельных значений. Это круто!
user31415

2
У меня не работает в Python 3 (массив остается логическим). Но использование numpy.multiply(B,1)работает.
Алаа М.

это работает для меня в python 3! и такое гениальное решение. о мой
всегда спрашиваювопросы

@Ourobours: Попытка последовать вашему предложению не сработала для меня. Хотя исходный sulotion дал хорошие, работоспособные результаты, B=map(int,B)мне вернули объект карты в python 3.
Eulenfuchswiesel

1
@Eulenfuchswiesel Это потому, что map возвращает итератор в Python3. Чтобы использовать его как список, преобразуйте его как список, например: B = list (map (int, B))
Gigi Bayte 2,

11

Вы можете использовать, x.astype('uint8')где xнаходится ваш логический массив.


9

Вот еще одно решение вашей проблемы:

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

Это работает , потому что сумма ASCII кодов 'true'IS 448, что даже, в то время как сумма ASCII кодов 'false'IS , 523который является нечетной.


Самое забавное в этом решении то, что его результат довольно случайный, если вход не является одним из 'true'или 'false'. Половину времени он вернется 0, а другую половину 1. Вариант с использованием encodeвызовет ошибку кодирования, если ввод не является ASCII (что увеличивает неопределенность поведения).


Серьезно, я считаю, что наиболее читаемым и быстрым решением будет использование if:

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

См. Некоторые микробенчмарки:

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

Обратите внимание, что это ifрешение как минимум в 2,5 раза быстрее, чем все другие решения. Это не имеет смысла ставить как требование , чтобы избежать использования ifS , за исключением , если это какое - то домашний (в этом случае вы не должны были спросить это в первую очередь).


7

Если вам нужно универсальное преобразование из строки, которая сама по себе не является логическим значением, вам лучше написать процедуру, аналогичную изображенной ниже. Следуя духу утиной печати, я не пропустил ошибку молча, а преобразовал ее в соответствии с текущим сценарием.

>>> 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
Почему TypeError? Если строка не содержит 'true'или 'false'это ошибка значения . Если ввод не является строкой, вы получите (в 99,99% случаев) AttributeErrorвместо этого, поэтому бесполезно ловить ValueErrorи повторно поднимать его как TypeError.
Bakuriu

@Bakuriu: Согласен. TypeError здесь действительно неприменим.
Abhijit

@Bakuriu: просто из любопытства, не могли бы вы привести пример вызова indexAttributeError?
georg

@Bakuriu: Я предполагаю , что я скорее со ссылкой на свой пост ниже: return ['false', 'true'].index(s) except (ValueError, AttributeError).
georg

@ thg435 В этом посте я просто скопировал и решил удалить lower()вызов, поскольку это было единственное решение, которое выполняло эти дополнительные вычисления, и было бы неправильно включать его в микротест. Конечно, это try...exceptзаймет немного времени, но разница небольшая, если исключение не возникает (например, 20nsменьше или около того).
Bakuriu

0

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

Теперь x содержит 1, если x == 'true'еще 0.

Примечание: x == 'true'вернет bool, который затем будет преобразован в int, имеющий значение (1, если значение bool равно True, иначе 0) при добавлении с 0.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.