【问题标题】:Using logical operators instead of control flow?使用逻辑运算符而不是控制流?
【发布时间】:2021-06-11 03:21:21
【问题描述】:

我会保持简短。 我正在审查十六进制过滤器的代码(过滤掉非字符 ASCII 值)

代码:

HEX_FILTER = ''.join([(len(repr(chr(i))) == 3) and chr(i) or '.' for i in range(256)])

输出:

................................ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[.]^_`abcdefghijklmnopqrstuvwxyz{|}~..................................¡¢£¤¥¦§¨©ª«¬.®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ

我对发生的事情感到困惑,所以我写了我的方法来获得高于输出。我的代码如下:

HEX_FILTER = ''.join(['.' if (len(repr(chr(i))) != 3) else chr(i) for i in range(256)])

这个想法是repr 的非字母将超过 3。如果不是 3 使用 '.'否则使用该字符。

我无法思考len(repr(chr(i))) == 3) and chr(i) or '.' 等于'.' if (len(repr(chr(i))) != 3) else chr(i) 的方式

【问题讨论】:

  • 查看是否存在差异的一种简单方法是编写一个脚本来循环遍历 2 个代码版本的 3 个部分的所有 T/F 值,并打印出一个真值表每个。只有 2^3 = 8 种组合。但也许你已经知道没有区别,因为那是你的问题......
  • 是的,我知道这两个代码产生相同的结果。我有点惊讶地注意到andor 被使用而不是ifelse。这让我想知道,其中哪一个在时间复杂度方面是有效的。有没有办法在复杂的 if-else 分支中使用 andor,更多关于幕后发生的事情
  • @xdhmoore andor 运算符适用于支持在布尔上下文中评估的 any 对象,因此有 许多更多可能的组合进行测试。
  • @mkrieger1 是的,我认为你是对的。特别是因为 AND/OR 运算符不会转换为布尔值,而是通过原始值作为 trincot 的答案提到的。

标签: python python-3.x string if-statement logical-operators


【解决方案1】:

原始表达式利用了这样一个事实:像andor 这样的布尔运算符总是计算为操作数之一,不一定是布尔值。这在某种程度上是对布尔逻辑的数学概念的扩展,其中所有涉及的值都是布尔值。

所以:

  • 如果and 运算符的左操作数是:

    • truthy,该操作将计算出 second 操作数是什么。
    • falsy,该操作将计算出 first(falsy)操作数是什么。
  • 如果or 运算符的左操作数是:

    • truthy,该操作将评估任何 first(真实)操作数。
    • falsy,该操作将计算出 second 操作数是什么。

如果将这些规则应用于表达式,您可以看到第一个表达式是一个真正的布尔值。如果它是假的,and 操作也将评估为假,然后作为or 操作符的左操作数。因此,or 操作将评估为最右边的操作数,即'.'

另一方面,如果第一个表达式为 True,则 and 运算符将计算为第二个操作数,即 chr(i)。该值恰好是 always 真实的,因为它永远不会是空字符串,因此 or 操作将只计算该值,甚至不会考虑最终操作数。

所以这两个构造是等价的,但仅当中间操作数(在本例中为 chr(i))始终为真时。

【讨论】:

  • 好的,这个精彩的解释清楚了,但这不违背 Python 之禅 - 可读性很重要。
  • 当然,为了便于阅读,我也会选择if...else,但我敢肯定有一群编码人员不这么认为。最后还是见仁见智吧。
猜你喜欢
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多