ChatGPT解决这个技术问题 Extra ChatGPT

How to convert 'false' to 0 and 'true' to 1?

Is there a way to convert true of type unicode to 1 and false of type unicode to 0 (in Python)?

For example: x == 'true' and type(x) == unicode

I want x = 1

PS: I don’t want to use if-else.


M
Martijn Pieters

Use int() on a boolean test:

x = int(x == 'true')

int() turns the boolean into 1 or 0. Note that any value not equal to 'true' will result in 0 being returned.


This is a wonderful answer except that everything sans 'true' would be interpreted as '0'. Not sure if that would suit OPs requirement.
Although it's probably what the OP wanted, it doesn't exactly match the question as asked for python 2.7. They explicitly asked for it to work on type unicode and did not specify the behaviour for type str.
@wim Actually the question never mentions a python versions, let alone the fact that it should be python2. 7. Also note that in python2 u'true' == 'true' so the function behaves correctly indipendently from the input type [between str and unicode].
And the python version of 2.x is implicit in the mention of unicode (in py 3k it's all just str)
@AlbertChen: no, because numpy arrays broadcast comparisons and don't produce a boolean value. Instead, comparisons produce an array of boolean values. I'm not sure what you expect from an arrayvalue == 'true' comparison, the question I answered here is specific to a string (unicode) value.
P
Peter Mortensen

If B is a Boolean array, write

B = B*1

(A bit code golfy.)


This exact same thing also works for single values. This is great!
Doesn't work for me in Python 3 (array stays boolean). But using numpy.multiply(B,1) works.
this works for me in python 3! and such brilliant solution. oh my
@Ourobours: Trying to follow your suggestion did not work for me.While the original sulotion gave a nice, workable results B=map(int,B) returned a map obejct in python 3 for me.
@Eulenfuchswiesel This is because map returns an iterator in Python3. To use it as a list, cast it as a list like so: B = list(map(int, B))
P
Peter Mortensen

You can use x.astype('uint8') where x is your Boolean array.


P
Peter Mortensen

Here's a yet another solution to your problem:

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

It works because the sum of the ASCII codes of 'true' is 448, which is even, while the sum of the ASCII codes of 'false' is 523 which is odd.

The funny thing about this solution is that its result is pretty random if the input is not one of 'true' or 'false'. Half of the time it will return 0, and the other half 1. The variant using encode will raise an encoding error if the input is not ASCII (thus increasing the undefined-ness of the behaviour).

Seriously, I believe the most readable, and faster, solution is to use an if:

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

See some microbenchmarks:

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

Notice how the if solution is at least 2.5x times faster than all the other solutions. It does not make sense to put as a requirement to avoid using ifs except if this is some kind of homework (in which case you shouldn't have asked this in the first place).


You can improve on the int-cast performance by binding the global to a local: def intcast(v, _int=int): return _int(v == "true"). It won't quite beat the conditional expression, however.
Closer is def setcontains(v, _s=frozenset(('true',))): return v in _s, almost as fast.
A
Abhijit

If you need a general purpose conversion from a string which per se is not a bool, you should better write a routine similar to the one depicted below. In keeping with the spirit of duck typing, I have not silently passed the error but converted it as appropriate for the current scenario.

>>> 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

Why a TypeError? If the string doesn't contain 'true' or 'false' it's a value error. If the input is not a string you'll get (99.99% of the times) an AttributeError instead, hence it's useless to catch for ValueError and re-raise it as TypeError.
@Bakuriu: I agree. TypeError was indeed not applicable here.
@Bakuriu: just out of curiosity, could you give an example of index raising an AttributeError?
@Bakuriu: I guess I was rather referring to your post below: return ['false', 'true'].index(s) except (ValueError, AttributeError).
@thg435 In that post I just copy-pasted and decided to remove the lower() call since this was the only solution that did this extra computation and it wouldn't have been correct to include it in the micro-benchmark. Sure even the try...except take a bit of time, but the difference is small if no exception is raised (like 20ns less or so).
p
prodyte

+(False) converts to 0 and +(True) converts to 1


That's for the True/False objects, not for the strings
I agree that this answer doesn't really answer that of the OP, but it's nevertheless a really interesting idiom, in particular when used in f-string contexts, where one can get rid of the parenthesis.
L
Leroy Scandal

Any of the following will work:

s = "true"

(s == 'true').real
1

(s == 'false').real
0

(s == 'true').conjugate()    
1

(s == '').conjugate()
0

(s == 'true').__int__()
1

(s == 'opal').__int__()    
0


def as_int(s):
    return (s == 'true').__int__()

>>>> as_int('false')
0
>>>> as_int('true')
1

Calculuswhiz, I appreciate the assist. Thank you Sir.
M
M C Akash

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

Now the x contains 1 if x == 'true' else 0.

Note: x == 'true' will return bool which then will be typecasted to int having value (1 if bool value is True else 0) when added with 0.


F
Fernando Pascoal Gomes

only with this:

const a = true; const b = false;

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