How to make a line break on the Python ternary operator?

PythonLine Breaks

Python Problem Overview


Sometimes a line containing a ternary operator in Python gets too long:

answer = 'Ten for that? You must be mad!' if does_not_haggle(brian) else "It's worth ten if it's worth a shekel."

Is there a recommended way to make a line break at 79 characters with a ternary operator? I did not find it in https://www.python.org/dev/peps/pep-0008/">PEP 8.

Python Solutions


Solution 1 - Python

You can always extend a logical line across multiple physical lines with parentheses:

answer = (
    'Ten for that? You must be mad!' if does_not_haggle(brian)
    else "It's worth ten if it's worth a shekel.")

This is called implicit line joining.

The above uses the PEP8 everything-indented-one-step-more style (called a hanging indent). You can also indent extra lines to match the opening parenthesis:

answer = ('Ten for that? You must be mad!' if does_not_haggle(brian)
          else "It's worth ten if it's worth a shekel.")

but this leaves you hitting the 80-column maximum all the faster.

Where precisely you put the if and else portions is up to you; I used my personal preference above, but there is no specific style for the operator that anyone agrees on, yet.

Solution 2 - Python

PEP8 says the preferred way of breaking long lines is using parentheses:

> The preferred way of wrapping long lines is by using Python's implied > line continuation inside parentheses, brackets and braces. Long lines > can be broken over multiple lines by wrapping expressions in > parentheses. These should be used in preference to using a backslash > for line continuation.

answer = ('Ten for that? You must be mad!'
          if does_not_haggle(brian)
          else "It's worth ten if it's worth a shekel.")

Solution 3 - Python

Bear in mind this advice from The Zen of Python: "Readability counts."

The ternary operator is most readable when it is all on one line.

x = y if z else w

When your conditions or variables push the line past 79 characters (see PEP8), readability begins to suffer. (Readability is also why dict/list comprehensions are best kept short.)

So, rather than trying to break the line using parentheses, you might find it is more readable if you convert it to a regular if block.

if does_not_haggle(brian):
    answer = 'Ten for that? You must be mad!'
else:
    answer = "It's worth ten if it's worth a shekel."

BONUS: The above refactoring reveals another readability issue: does_not_haggle is inverted logic. This would be even more readable, if you can rewrite the function:

if haggles(brian):
    answer = "It's worth ten if it's worth a shekel."
else:
    answer = 'Ten for that? You must be mad!'

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionnedimView Question on Stackoverflow
Solution 1 - PythonMartijn PietersView Answer on Stackoverflow
Solution 2 - PythonPeter WoodView Answer on Stackoverflow
Solution 3 - PythonJohn AndersonView Answer on Stackoverflow