如何将“false”转换为0,“true”转换为1?

175
有没有一种方法可以将类型为unicodetrue转换为1,将false转换为0(在Python中)?
例如:x == 'true' and type(x) == unicode 我想要x = 1 PS:我不想使用if-else
9个回答

221

在布尔测试中使用int()

x = int(x == 'true')

int()将布尔值转换为10。请注意,任何值不等于'true'都会返回0


1
这是一个很好的答案,除了没有'true'的所有内容都会被解释为'0'。不确定是否符合OP的要求。 - Abhijit
虽然这可能是OP想要的,但它并不完全符合Python 2.7所要求的问题。他们明确要求它在类型unicode上工作,并没有指定类型str的行为。 - wim
1
@wim 实际上,这个问题从来没有提到过Python版本,更不用说它应该是Python2.7了。此外,请注意,在Python2中,u'true' == 'true',因此该函数的行为与输入类型[str和unicode之间]无关。 - Bakuriu
1
Python 2.x版本的隐含意思是Unicode的提及(在Python 3K中,所有都是str)。 - wim
1
@AlbertChen:不行,因为NumPy数组会广播比较,并且不会产生布尔值。相反,比较会生成一个布尔值数组。我不确定您对arrayvalue == 'true'比较的期望是什么,我在这里回答的问题是针对字符串(Unicode)值的特定问题。 - Martijn Pieters
显示剩余3条评论

194
如果B是一个布尔型数组,请编写:
B = B*1
(这有点像代码高尔夫。)

2
同样的方法也适用于单个值。这太棒了! - user31415
3
在 Python 3 中对我不起作用(数组仍然是布尔值)。但是使用 numpy.multiply(B,1) 就可以了。 - Alaa M.
FWIW,这个解决方案适用于 pandas 的列:df['x'] = df['x'] * 1 - Tom
1
@Eulenfuchswiesel 这是因为在Python3中,map返回一个迭代器。要将其用作列表,请将其转换为列表,如下所示:B = list(map(int, B)) - Gigi Bayte 2
或者只是 B *= 1 - Rehan Haider
显示剩余3条评论

19

您可以使用 x.astype('uint8'),其中 x 是您的布尔数组。


11

这里有另一个解决您问题的方案:

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

这段代码之所以有效,是因为'true'的ASCII码之和为448,为偶数,而'false'的ASCII码之和为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倍。除非这是某种作业(在这种情况下,您本来就不应该首先提出这个问题),否则没有理由要求避免使用if

你可以通过将全局变量绑定到本地变量来提高int-cast性能:def intcast(v, _int=int): return _int(v == "true")。但是它不会完全击败条件表达式。 - Martijn Pieters
Closer是def setcontains(v, _s=frozenset(('true',))): return v in _s,速度几乎一样快。 - Martijn Pieters

8

+(False) 将转换为 0,并且 +(True) 将转换为 1。


1
那是针对True/False对象的,而不是针对字符串。 - étale-cohomology
1
我同意这个答案并没有真正回答OP的问题,但它仍然是一个非常有趣的习语,特别是在f-string上下文中使用时,可以摆脱括号。 - ncarrier

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:只是出于好奇,你能举个index引发AttributeError的例子吗? - georg
@Bakuriu: 我想我更多是指的你下面的帖子:return ['false', 'true'].index(s) except (ValueError, AttributeError) - georg
@thg435 在那篇帖子中,我只是复制并决定删除 lower() 调用,因为这是唯一执行此额外计算的解决方案,将其包含在微基准测试中是不正确的。当然,即使 try...except 花费了一些时间,但如果没有引发异常(如少于 20ns),差异很小。 - Bakuriu
def to_bool(s): return s&1转换为布尔类型: def to_bool(s): return s&1 - Leroy Scandal

3
任何一个都可以起作用:
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,感谢您的帮助。谢谢您先生。 - Leroy Scandal

1

布尔值转整数:

x = (x == 'true') + 0

现在,如果x == 'true',则x包含1,否则为0。

注意:x == 'true'将返回布尔值,然后将其强制转换为整数,并与0相加得到值(如果布尔值为True,则为1,否则为0)。


-2

只有这些:

const a = true; const b = false;

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接