【问题标题】:How to convert 'false' to 0 and 'true' to 1?如何将“false”转换为 0,将“true”转换为 1?
【发布时间】:2014-01-17 09:55:03
【问题描述】:

有没有办法将unicode 类型的true 转换为1,将unicode 类型的false 转换为0(在Python 中)?

例如:x == 'true' and type(x) == unicode

我想要x = 1

PS:我不想用if-else

【问题讨论】:

    标签: python string integer


    【解决方案1】:

    在布尔测试中使用int()

    x = int(x == 'true')
    

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

    【讨论】:

    • 这是一个绝妙的答案,除了所有没有“真”的东西都将被解释为“0”。不确定这是否符合 OP 的要求。
    • 虽然这可能是 OP 想要的,但它与 python 2.7 的问题并不完全匹配。他们明确要求它适用于 unicode 类型,但没有指定 str 类型的行为。
    • @wim 实际上问题 never 提到了 python 版本,更不用说它应该是 python2 的事实了。 7。另请注意,在 python2 u'true' == 'true' 中,函数的行为与输入类型无关 [在 strunicode 之间]。
    • 2.x 的 python 版本隐含在提到 unicode(在 py 3k 中都只是 str)
    • @AlbertChen:不,因为 numpy 数组 broadcast comparisons 并且不会产生布尔值。相反,比较会产生一个布尔值的array。我不确定您对 arrayvalue == 'true' 比较的期望,我在这里回答的问题是特定于字符串(unicode)值的。
    【解决方案2】:

    如果B是一个布尔数组,写

    B = B*1
    

    (有点代码高尔夫球。)

    【讨论】:

    • 这个完全相同的事情也适用于单个值。这太棒了!
    • 在 Python 3 中对我不起作用(数组保持布尔值)。但是使用numpy.multiply(B,1) 可以。
    • 这适用于我在 python 3 中!以及如此出色的解决方案。哦,我的
    • @Ourobours:尝试遵循您的建议对我不起作用。虽然最初的 sulition 给出了一个不错的、可行的结果 B=map(int,B) 在 python 3 中为我返回了一个地图对象。
    • @Eulenfuchswiesel 这是因为 map 在 Python3 中返回一个迭代器。要将其用作列表,请将其转换为列表,如下所示: B = list(map(int, B))
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      这是解决您问题的另一种方法:

      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。如果输入不是 ASCII,则使用 encode 的变体将引发编码错误(从而增加行为的不确定性)。


      说真的,我相信最易读、而且速度更快的解决方案是使用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.5x所有 其他解决方案. 要求避免使用ifs 是有意义的,除非这是某种家庭作业(在这种情况下,您一开始就不应该问这个问题)。

      【讨论】:

      • 您可以通过将全局绑定到本地来提高 int-cast 性能:def intcast(v, _int=int): return _int(v == "true")。但是,它不会完全胜过条件表达式。
      • 更接近def setcontains(v, _s=frozenset(('true',))): return v in _s几乎一样快。
      【解决方案5】:

      如果您需要从本身不是布尔值的字符串进行通用转换,您最好编写一个类似于下面描述的例程。为了与鸭子打字的精神保持一致,我没有默默地传递错误,而是将其转换为适合当前场景。

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

      【讨论】:

      • 为什么是TypeError?如果 string 不包含 'true''false' 这是一个 value 错误。如果输入不是字符串,您将得到(99.99% 的时间)AttributeError,因此捕获ValueError 并将其重新提升为TypeError 是没有用的。
      • @Bakuriu:我同意。 TypeError 在这里确实不适用。
      • @Bakuriu:出于好奇,你能举一个index引发AttributeError的例子吗?
      • @Bakuriu:我想我是指您在下面的帖子:return ['false', 'true'].index(s) except (ValueError, AttributeError)
      • @thg435 在那篇文章中,我只是复制粘贴并决定删除lower() 调用,因为这是进行此额外计算的唯一解决方案,并且将其包含在其中是不正确的微基准。当然,即使try...except 也需要一些时间,但如果没有引发异常(比如20ns 更少左右),差异就会很小。
      【解决方案6】:

      +(False) 转换为 0 和 +(True) 转换为 1

      【讨论】:

      • 这是针对True/False 对象的,不是针对字符串的
      • 我同意这个答案并没有真正回答 OP 的答案,但它仍然是一个非常有趣的习语,特别是在 f-string 上下文中使用时,可以去掉括号。
      【解决方案7】:

      以下任何一种都可以:

      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,感谢您的帮助。谢谢先生。
      【解决方案8】:

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

      现在 x 包含 1 if x == 'true' else 0。

      注意:x == 'true' 将返回 bool,然后在添加 0 时将其类型转换为具有值的 int(如果 bool 值为 True,则为 1,否则为 0)。

      【讨论】:

        【解决方案9】:

        只有这个:

        常量 a = true; 常量 b = false;

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

        【讨论】:

          猜你喜欢
          • 2011-12-16
          • 2013-04-25
          • 2019-12-28
          • 1970-01-01
          • 1970-01-01
          • 2019-01-06
          • 2018-04-02
          • 2020-07-06
          • 1970-01-01
          相关资源
          最近更新 更多