user14354509
user14354509

Reputation: 47

Using logical operators instead of control flow?

I will keep this short. I was reviewing code for Hex Filter (To filter out non-character ASCII values)

code:

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

Output:

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

I was confused on what's going on, so I wrote my approach to get above output. My code is as follows:

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

The idea is repr of non-alphabet will be more than 3. If it's not 3 use '.' else use the character.

I cannot wrap my mind around on as to, How len(repr(chr(i))) == 3) and chr(i) or '.' equates to '.' if (len(repr(chr(i))) != 3) else chr(i)

Upvotes: 0

Views: 119

Answers (1)

trincot
trincot

Reputation: 350137

The original expression makes use of the fact that a boolean operator like and and or always evaluates to one of the operands, not necessarily a boolean. This is somewhat an extension to the mathematical notion of boolean logic where all involved values are booleans.

So:

  • if the left operand of an and operator is:

    • truthy, the operation will evaluate to whatever the second operand is.
    • falsy, the operation will evaluate to whatever the first (falsy) operand is.
  • if the left operand of an or operator is:

    • truthy, the operation will evaluate to whatever the first (truthy) operand is.
    • falsy, the operation will evaluate to whatever the second operand is.

If you apply those rules to the expression, you can see that the first expression is a true boolean. In case it is false, the and operation will also evaluate to false, which then serves as the left operand to the or operator. By consequence, the or operation will evaluate to the rightmost operand, i.e. to '.'.

If on the other hand the first expression is True, then the and operator will evaluate to the second operand, i.e. chr(i). That value happens to be always truthy, as it can never be the empty string, and so the or operation will just evaluate to that and will not even consider the final operand.

So the two constructs are equivalent, but only when the middle operand (in this case chr(i)) is always truthy.

Upvotes: 2

Related Questions