TL; DR
We begin by summarizing the two behaviors of the two logical operators and and or . These idioms will form the basis of our discussion below.
and
Return the first Falsy value, if any, otherwise return the last value in the expression.
or
Return the first value of Truthy, if it is, otherwise return the last value in the expression.
The behavior is also summarized in the documents , especially in this table:

The only operator that returns a boolean regardless of its operands is the not operator.
Grades "Truth" and "Truth"
Statement
len(args) and max(args) - min(args)
This is a very pythonic concise (and perhaps less readable) way of saying "if args not empty, return the result max(args) - min(args) ", otherwise return 0 . In general, this is a more concise representation of the if-else . For example,
exp1 and exp2
Should (approximately) translate to:
r1 = exp1 if not r1: r1 = exp2
Or, equivalently,
r1 = exp1 if exp1 else exp2
Where exp1 and exp2 are arbitrary python objects or expressions that return some object. The key to understanding the use of logical and and or operators here is the understanding that they are not limited to working or returning logical values. Any object with a truth value can be checked here. This includes int , str , list , dict , tuple , set , NoneType and user-defined objects. Short circuit rules still apply.
But what is truthfulness?
This refers to how objects are evaluated when used in conditional expressions. @Patrick Haugh describes the truth well in this post .
All values ββare considered "true", except for the following, which are "false":
NoneFalse00.00jDecimal(0)Fraction(0, 1)[] - empty list{} - empty dict() - empty tuple'' - empty strb'' - empty bytesset() - empty set- empty
range e.g. range(0) - objects for which
obj.__bool__() returns Falseobj.__len__() returns 0
A true value will satisfy the test performed by if or while if . We use "truth" and "false" to distinguish between bool True and False .
How and works
We are building on the OP question as a transition to a discussion about how these operators are in these cases.
Given a function with a definition
def foo(*args): ...
How to return the difference between the minimum and maximum value in the list from zero or more arguments?
Finding the minimum and maximum is easy (use the built-in functions!). The only catch here is to properly handle the corner case where the argument list may be empty (for example, call foo() ). We can do it in one line, thanks to the use of and operator:
def foo(*args): return len(args) and max(args) - min(args)
foo(1, 2, 3, 4, 5)
Since and used, the second expression should also be evaluated if the first is True . Note that if the first expression evaluates to true, the return value is always the result of the second expression. If the first expression evaluates to false, then the return result is the result of the first expression.
In the above function, if foo takes one or more arguments, len(args) greater than 0 (a positive number), so the return result is max(args) - min(args) . OTOH, if no arguments are passed, len(args) is 0 which is false, and 0 returned.
Note that an alternative way to write this function is:
def foo(*args): if not len(args): return 0 return max(args) - min(args)
Or, more briefly,
def foo(*args): return 0 if not args else max(args) - min(args)
If, of course, none of these functions performs any type checking, so if you do not fully trust the input provided, do not rely on the simplicity of these constructions.
How or works
I explain the work of or in a similar way with a far-fetched example.
Given a function with a definition
def foo(*args): ...
How would you complete foo to return all numbers over 9000 ?
We use or to handle the corner case here. We define foo as:
def foo(*args): return [x for x in args if x > 9000] or 'No number over 9000!' foo(9004, 1, 2, 500)
foo filters the list to save all numbers over 9000 . If such numbers exist, the result of understanding the list is a non-empty list, which is Truth, so it returns (short circuit in action here). If such numbers do not exist, then the result of the comp list will be [] is Falsy. Thus, the second expression is now evaluated (non-empty string) and returned.
Using conditional expressions, we could rewrite this function as
def foo(*args): r = [x for x in args if x > 9000] if not r: return 'No number over 9000!' return r
As before, this structure is more flexible in terms of error handling.