Is the "or" used on the right side of the pythonic job?

Situation

(Note: the following situation is merely exemplary. This question applies to everything that can be rated as bool)

Use the default list if the user does not provide their own list:

default_list = ... custom_list = ... if custom_list: list = custom_list else: list = default_list 

You can reduce this value to:

 default_list = ... custom_list = ... list = custom_list if custom_list else default_list 

Now, according to https://docs.python.org/2.7/reference/expressions.html#or ...

The expression x or y first evaluates x ; if x is true, its value is returned; otherwise, y is computed and the return value is returned.

..., or does not return a boolean, but rather a first value whose boolean conversion is not false. Therefore, the following code is valid:

 list = custom_list or default_list 

This is similar to the C # Null Coalescing Operator, except that it should be deferred in Python as a False Coalescing Operator, which returns the first invalid argument.

Question

The last example seems easier to read, but is it considered pythonic?

Neither pep8 (program) nor pylint complain.

+6
source share
2 answers

This is perfectly true, and you can use it. Even for the or documentation , an example is provided for this.

Note that neither one, nor the constraint or type of value returns to False and True , but rather returns the last evaluated argument. This is sometimes useful, for example, if s is a string that should be replaced with a default value, if it is empty, the expression s or 'foo' gives the desired value.

However, the or method has a limitation. If you want to specifically enable the Non-Truthy value, then this is not possible.

Suppose you want to allow an empty list

 my_list = [] or default_list 

will always give default_list . For instance,

 print [] or [1, 2, 3] # [1, 2, 3] 

But with a conditional expression, we can handle it this way:

 custom_list if isinstance(custom_list, list) else default_list 

Recycling old documents, quoting the BDFL FAQ ,

4.16. Q. Is there an equivalent C "?:" Ternary operator?

a. Not directly. In many cases, you can simulate a?b:c using a and b or c , but there is a drawback: if b is zero (or empty or None - anything that checks false), then c will be selected. In many cases, you can prove by looking at the code that this cannot happen (for example, because b is a constant or has a type that can never be false), but in general this can be a problem.

Steve Majewski (or was it Tim Peters?) Proposed the following Solution: (a and [b] or [c])[0] . Since [b] is a singleton list, it is never false, so the wrong path is never accepted; then applying [0] to it all gets the b or c that you really wanted. Ugly, but it gets there on rare occasions when it is really inconvenient to rewrite your code using "if".

+4
source

Yes, using or , for this, short circuit properties were the norm before the conditional expression construct was added to the language.

It was and still is beautiful pythons:

 foo = bar or baz 

to return to default if bar is false-y (false in a boolean context). The fact that this short circuit also allows you to do things like:

 foo = bar or expensive_calculation(baz) # only if bar is false-y 

and does not have expensive_calculation() to execute if bar is true-y (calculated as true in a boolean context). Similarly, you can use and to enforce the prerequisites:

 foo = bar and bar(baz) # call `bar()` only if it is truth-y 

You must use a conditional expression to:

 foo = bar and spam or eggs 

but. That the conditional expression seeks to replace. The idea was that if bar is true-y, then spam is chosen, otherwise eggs selected. But it breaks if spam false-y! It was a common source of errors, and

 foo = spam if bar else eggs 

always selects spam if bar is true-y.

+4
source

All Articles