(PEP-308) Python's Conditional Selection Operators
Terry Reedy
tjreedy at udel.edu
Fri Feb 14 19:24:50 EST 2003
More information about the Python-list mailing list
Fri Feb 14 19:24:50 EST 2003
- Previous message (by thread): (PEP-308) Python's Conditional Selection Operators
- Next message (by thread): (PEP-308) Python's Conditional Selection Operators
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
PYTHON'S CONDITIONAL SELECTION OPERATORS: 'AND' AND 'OR' Some slightly different thougths (as of 2003 Feb 14) ... Conflicting meanings -------------------- Python's 'and' and 'or' are not the standard versions: In logic, math, and computing science, 'and' and 'or' have well-known standard meanings as logical operators, either strict or domain-extended via operand coercion, and either conditional in execution or not. In Python, 'and' and 'or' are generalized as conditional selection operators (as explained in following sections), with some unusual properties. The difference is slightly tricky. When both operands are logical values, the selection result is the same as in strict logic. On the extended domain, the result is usually different from that of the corresponding extended logical operator. But coercing the result to boolean washes away the difference.. Logic and conditional execution: -------------------------------- Binary logic operators map two logic values to a logic value. The domain can be extended by implicitly coercing non-logic values to logic values. The result is still a logic value: a extended-op b == bool(a) strict-op bool(b). Like multiplication, where 0*a=0, logical 'and' and 'or' have dominant values: 0 and a = 0, 1 or a = 1, where 0,1 are False, True. For efficiency, execution of the second operand can be conditional on the first not being dominant. The possible problem is when execution of b has a side-effect that also becomes conditional. Conditional statements (if, elif, else) extend conditional execution from expressions to blocks of code. Python's conditional statements are lax (like extended operaters) in that they accept any expression as a condition and then implicitly coerce the result to a boolean value: if bool(expression): # has the same effect as if expression: In a sense, conditional statements makes conditional (extended) logic operators redundant: tem = a and b # is equivalent to tem = bool(a) if tem: tem = bool(b) tem = a or b # is equivalent to tem = bool(a) if not tem: tem = bool(b) However, they are still very convenient to have. Selection and Logic ------------------- A selection operation selects one (or more) items from many. The getitem/getattribute operator [a] selects an item from a collection object. Slices select contiguous chunks from sequences. Filter() selects 0 to all items produced by an iterable. In Python, 'and' and 'or' conditionally select one of their two operands: tem = a and b # is equivalent to tem = a if tem: tem = b tem = a or b # is equivalent to tem = a if not tem: tem = b These statement equivalents are identical, except for omission of bool() coercions, to the statements equivalent to conditional extended logic ops. When both a and b are boolean, so is the output, making selection and logic the same. They are also the same when the selection result is coerced to boolean. Since if and elif implicitly do such coercion, selection acts like logic when it is the outer operation of an if/elif condition. But in other contexts, it does not. Thus, the effect of 'if (a and b):' does not depend on which meaning 'and' has, while that of 'if (a and 2)==2:' does. A non-trival binary logic operator is one whose output depends on both inputs. Of the ten possible, only and and or are selective in that the output is always one of the inputs. (To be selective, 0 op 0 and 1 op 1 must be 0 and 1 respectively. Of the four possible assignments to 0 op 1 and 1 op 0, two produce the trivial selectors a op b == a and a op b == b. The other two are and and or.) They are thus the only two that can be generalized in the way they are in Python. Selective 'and' and 'or' ------------------------ The 'conditional' aspect of Python's 'and' and 'or' can be used to guard execution of a possibly impossible or illegal expression. When a null default is acceptible, 'possible and expression' works. If a truthful default is wanted, then use 'impossible or expression' instead. Selective 'and' and 'or' have an unusual combination of properties. Every Python value is a left identity (id op b == b) for one of the two. They are non-commutative (in general, a op b != b op a) but become commutative when coerced to boolean. Both are associative ((a and b) and c) == a and (b and c); (a or b) or c == a or (b or c)) as can be verified by truth-outcome tables. Iterated 'a and b and ... and z' selects the first null value or the default z. Iterated 'a or b or ... or z' selects the first non-null value or, again, the last. The mixed combinations 'a and (b or c)' and 'a or (b and c)' select one of the three inputs, depending of the truth values of a and b. The first selects the first of null a, non-null b, or any c. The second switches null and non-null. Expressions parenthesized to the right sequentially examine values and select the first whose boolean value dominates the following operator. The reversed expressions '(a and b) or c' and '(not a or b) and c' are the most relevant to PEP-308 and the quest for an 'if a then b else c' ternary. When a is False, both select c. When a is True, the first selects True b while the second selects False b. So if we know the truth value of one of the selection targets, there is an and/or combination that gives the right answer. For instance, if x then x.val else 0 == (x or 0) and x.val. For the general case, the two expressions combine to exactly match 'if a then b else c': (a and b) or ((not a or b) and c) == (not a or b) and ((a and b) or c). However, these are sufficiently baroque that most any of the current or proposed alternatives should be better. Terry J. Reedy
- Previous message (by thread): (PEP-308) Python's Conditional Selection Operators
- Next message (by thread): (PEP-308) Python's Conditional Selection Operators
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list