Why is operator module missing `and` and `or`?

python operator module
python itemgetter sort
__mul__ python
python operators
python operator overloading
how to use __lt__ python
itemgetter example
python __lt__ example

operator module makes it easy to avoid unnecessary functions and lambdas in situations like this:

import operator

def mytest(op, list1, list2):
    ok = [op(i1, i2) for i1, i2 in zip(list1, list2)]
    return all(ok)

mytest(operator.eq, [1, 2, 3], [1, 2, 3])         # True
mytest(operator.add, [-1, 2, -3], [1, -2, 33])    # False

Well, now I need to do i1 and i2, but to my surprise, I can't find and in the operator module! And the same applies to or! I know, and is not exactly operator, it's a keyword, but not, along with is and even del, are all keywords and all are included.

So what's the story? Why are they missing?

Because you cannot convert boolean operators into python functions. Functions always evaluate their arguments, and boolean operators do not. Adding and and or to the operators module would also require adding a special kind of functions (like lisp "macros") that evaluate their arguments on demand. Obviously, this is not something python designers ever wanted. Consider:

if obj is not None and obj.is_valid():
    ....

you cannot write this in a functional form. An attempt like

  if operator.xyz(obj is not None, obj.is_valid()) 

will fail if obj is actually None.

operator — Standard operators as functions, All definitions are evaluated to a module value representing the path within the current Recursive definitions are evaluated, as usual, via a fixpoint operator. Missing definitions are assigned by gluing modules over the function sum. The logical operator *NOT (or ¬) is used to negate logical variables or constants. Any *NOT operators must be evaluated before the *AND or *OR operators are evaluated. Any values that follow *NOT operators must be evaluated before the logical relationship between the operands is evaluated.

You can write these yourself, but you'll need to pass a function (e.g. lambda) for the second argument to prevent it from being evaluated at call time, assuming that the usual short-circuiting behavior is important to you.

def func_or(val1, fval2):
    return val1 or fval2()

def func_and(val1, fval2):
    return val1 and fval2()

Usage:

func_or(False, lambda: True)
func_and(True, lambda: False)

Trends in Functional Programming: 13th International Symposium, , Many SAS/IML built-in subroutines and matrix operators handle missing values Similarly, the Median module (which is distributed with SAS/IML as part of the  REACT TO OPERATOR ERROR When regulators are onsite con-ducting an inspection or any type of visit that leads to a review of the training or CAPA program, poten-tial follow-up questions are always asked regarding operator errors. The first and obvious question is: “Why wasn't the training effective?” This question can lead to scrutiny of the

The reason there's no operator.and is that and is a keyword, so that would be a SyntaxError.

As tgh435 explained, the reason there's no renamed and function in operator is that it would be misleading: a function call always evaluates its operands, but the and operator doesn't. (It would also be an exception to an otherwise consistent and simple rule.)


In your case, it looks like you don't actually care about short-circuiting at all, so can build your own version trivially:

def and_(a, b):
    return a and b

Or, if you're just using it once, even inline:

mytest(lambda a, b: a and b, [-1, 2, -3], [1, -2, 33])

In some cases, it's worth looking at all (and, for or, any). It is effectively short-circuited and expanded to arbitrary operands. Of course it has a different API than the operator functions, taking a single iterable of operands instead of two separate operands. And the way it short-circuits is different; it just stops iterating the iterable, which only helps if you've set things up so the iterable is only evaluating things as needed. So, it's usually not usable as a drop-in replacement—but it's sometimes usable if you refactor your code a bit.

Statistical Programming with SAS/IML Software, The operator module exports a set of efficient functions corresponding to the intrinsic operators of Python. For example, operator.add(x, y) is equivalent to the​  This operator acts similarly to the UNIX control operator ampersand (&), which runs the command before it asynchronously in sub shell as a job. This operator is functionally equivalent to Start-Job. By default, the background operator starts the jobs in the current working directory of the caller that started the parallel tasks.

Python's and and or syntaxes cannot directly be mapped to functions. These syntaxes are lazy evaluated: If the result of the left part of the expression allows to know the value of the whole expression, the right part is skipped. Since they introduce flow control, their behavior cannot be reproduced using an operator. To reduce confusion, python have chosen to simply not provide these methods.

georg gives a good example of a situation where and laziness matters:

 if obj is not None and obj.is_valid():
     ...

Now, if you don't need lazy evaluation, you can use abarnert's answer implementation:

def and_(a, b):
    return a and b

def or_(a, b):
    return a or b

Usage:

>>> or_(False, True)
>>> and_(True, False)

If you need lazy evaluation, you can use kindall's answer implementation:

def func_or(val1, fval2):
    return val1 or fval2()

def func_and(val1, fval2):
    return val1 and fval2()

Usage:

>>> func_or(False, lambda: True)
>>> func_and(True, lambda: False)

Note: As mentioned in the comments, the functions operator.and_ and operator.or_ correspond to the bitwise operators & and |. See: https://docs.python.org/3/library/operator.html#mapping-operators-to-functions

Note that the names operators.and and operators.or aren't used: and and or are Python keywords so it would be a syntax error.

9.9. operator — Standard operators as functions, The owner or operator shall record the causes of any missing data periods (v) Pressure differential across each operating scrubber module (inches of water  The PowerShell logical operators evaluate only the statements required to determine the truth value of the statement. If the left operand in a statement that contains the and operator is FALSE, the right operand is not evaluated. If the left operand in a statement that contains the or statement is TRUE, the right operand is not evaluated.

Federal Register, The owner or operator shall record the causes of any missing data periods and of slurry to each operating scrubber module (gal/min); (v) Pressure differential  operator.methodcaller (name, /, *args, **kwargs) ¶ Return a callable object that calls the method name on its operand. If additional arguments and/or keyword arguments are given, they will be given to the method as well.

Code of Federal Regulations, Operators¶. The Python operator module 0 contains a large variety of operators and iteration_utilities only tries to fill in some missing ones:  Dismiss Join GitHub today. GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.

Operators, sufficient to compensate for decreased turbulence to prevent missing and backfiring; Gears of module, circular or diametral pitch, can be readily cut, the tools The operator cannot just lean the article being roughed, a table spoon in this  In digital computer programming, a bitwise operation operates on one or more bit patterns or binary numerals at the level of their individual bits. It is a fast and simple action, directly supported by the processor, and is used to manipulate values for comparisons and calculations. On simple low-cost processors, typically, bitwise operations are substantially faster than division, several times faster than multiplication, and sometimes significantly faster than addition. While modern processors

Comments
  • operator.and_ and operator.or_ are both there. Same goes for the other keyword operators, you need the _.
  • operator.and_ and operator.or_ are the bitwise operators & and |, not the logical and and or.
  • As a side note, you don't really need ok to be a list here. If list1 and list2 can be very large, especially if it's likely that a false will show up pretty early in the list, you'd be much better off with a generator expression rather than a listcomp (and, if you're using 2.x, itertools.izip instead of zip).
  • In many cases, you're looking for something that's just like and or or, but doesn't short-circuit. In that case, you can just write a one-liner function (out of line, or as a lambda) and use that. The reason it isn't included in operator is that it's not the same as and (because it doesn't short-circuit), meaning (a) it might mislead people into thinking it is, and (b) it would spoil the nice clean design of "operators map to operator functions exactly".