使用逻辑运算符而不是控制流?

Using logical operators instead of control flow?

我会保持简短。 我正在审查十六进制过滤器的代码(过滤掉非字符 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)

,我想不通

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

所以:

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

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

    • truthy,该操作将评估 first(真实)操作数是什么。
    • falsy,该操作将评估为 second 操作数是什么。

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

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

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