【问题标题】:Is there any legitimate use of list[True], list[False] in Python?在 Python 中是否有任何合法使用 list[True]、list[False] 的方法?
【发布时间】:2016-11-02 05:18:58
【问题描述】:

由于TrueFalseint 的实例,以下在Python 中有效:

>>> l = [0, 1, 2]
>>> l[False]
0
>>> l[True]
1

我明白为什么会这样。但是,我发现这种行为有点出乎意料,并且可能导致难以调试的错误。它肯定咬了我好几次。

谁能想到用TrueFalse 合法使用索引列表?

【问题讨论】:

  • 对代码高尔夫有用:print(('ko', 'ok')[a
  • 它是有效的python代码,是否“合法”使用主要是见仁见智。
  • 有趣的讨论在这里:stackoverflow.com/questions/2764017/…
  • 请注意,在 numpy ndarray 中,它有不同的含义:np.array([1, 2, 3])[array([True, False, True])]array([1, 3])

标签: python boolean


【解决方案1】:

过去,有人利用这种行为制作了一个穷人的conditional expression

['foo', 'bar'][eggs > 5]  # produces 'bar' when eggs is 6 or higher, 'foo' otherwise

然而,proper conditional expression 已被添加到 Python 2.5 中的语言中,这非常令人不悦,因为您陈述的原因是:依赖布尔值作为整数的子类太“神奇”且不可读维护者。

所以,除非你在打代码(故意产生非常紧凑和晦涩的代码),否则使用

'bar' if eggs > 5 else 'foo'

相反,它具有额外的优势,即在此选择的两个表达式之间进行 惰性 评估;如果eggs > 5 为假,则永远不会执行if 之前的表达式。

【讨论】:

  • 但它实际上是如何工作的?马丁?我尝试了 list l = [2, 0, 1] 只是为了看看它产生了什么 adn False 返回 2 和 True 0..
  • @Ev.Kounis: True == 1, False == 0,因为布尔值是 int 的子类。由于eggs > 5 产生一个布尔值,但索引采用整数值,eggs > 5True 产生['foo', 'bar'][1],否则产生['foo', 'bar'][0]
  • 如果您要索引的实体是冗长的,替代形式是否仍然更清晰? x = available_options[choice].response_text[ int(n<9) ] 也许?我当然会主张始终将 int() 放在那里以使其更具可读性,即使它在语言定义上是无操作的。
  • @nigel222:我更喜欢opts = available_options[choice].response_textx = opts[0] if n < 9 else opts[1]
  • @Izkata:我真的没有发现更清楚,而且它在 Python 成语面前非常飞扬。
【解决方案2】:

如果您对为什么bool 是一个有效的索引参数感到困惑:这只是为了一致性,事实上boolint 的子类,而在Python 中它是数字类型。

如果您首先问为什么bool 是数字类型,那么您必须了解bool 在旧版本的Python 中不存在,人们使用ints 代替。

我将添加一些历史论据。首先在 Python 中添加 bool 在 Guido van Rossum(又名 BDFL)博客文章中进行了简短描述:The History of Python: The history of bool, True and False。该类型是通过PEP 285 添加的。

PEP 包含用于此决策的实际理由。我将在下面引用 PEP 的一些部分。

4) 我们是否应该努力消除对布尔值的非布尔运算 将来,通过适当的警告,例如 True+1 最终会(在 Python 3000 中)是非法的吗?

=> 没有。

有一小部分人愿意看到 不支持算术运算的“教科书”布尔值 全部,但大多数评论者都同意我的观点,布尔值应该始终 允许算术运算。


6) bool 是否应该从 int 继承?

=> 是的。

在理想情况下,bool 可能更好地实现为 知道如何执行混合模式的单独整数类型 算术。但是,int 继承 bool 可以简化 极大地实现(部分是因为所有调用的 C 代码 PyInt_Check() 将继续工作——这将返回 true int) 的子类。另外,我相信这是正确的 可替代性:需要int 的代码可以输入bool 它的行为与01 相同。需要的代码 bool 在被赋予int 时可能不起作用;例如,3 和 4 为 0,但 3 和 4 都为真 价值观。


因为bool 继承自int,所以True+1 有效且等于2,并且 很快。 这对于向后兼容很重要:因为 比较等当前返回整数值,没有 告诉现有应用程序如何使用这些的方式 价值观。


由于向后兼容,bool类型缺少很多 有些人希望看到的属性。例如,算术 允许带有一个或两个布尔参数的操作,处理 False 为 0,True 为 1。此外,bool 可以用作序列 索引。

我不认为这是一个问题,我不想进化 语言也朝这个方向。我不相信一个 对“布尔”的更严格解释使该语言 更清晰。


总结

  • 向后兼容性:很多代码已经使用ints 01 来表示FalseTrue,其中一些在数值计算中使用了这些值。
  • 拥有“非教科书”bool 类型并不是什么大不了的事
  • Python 社区中的很多人都想要这些功能
  • BDFL 是这么说的。

【讨论】:

    【解决方案3】:

    通常有更好的方法,但布尔索引确实有其用途。当我想将布尔结果转换为更易于阅读的内容时,我使用了它们:

    test_result = run_test()
    log.info("The test %s." % ('Failed', 'Passed')[test_result])
    

    【讨论】:

      猜你喜欢
      • 2014-06-21
      • 1970-01-01
      • 2012-12-03
      • 2017-06-21
      • 1970-01-01
      • 2013-10-09
      • 2012-11-24
      • 2022-07-11
      • 2018-01-15
      相关资源
      最近更新 更多