PEP 8 purists are ready to attack you and your code if they catch you not complying with the PEP 8 standard. For instance, Python coders put their braces, brackets, or parentheses into a separate line to make it easier to grasp nested lists or dictionaries.
This article shows how to line up the closing braces, brackets, and parentheses correctly in Python. This is called “hanging indentation” and it’s at the heart of PEP 8 standardized, clean code that’s easy to read and understand!
A quick example shows how you can create a multi-line construct that complies with the PEP 8 standard:
# PEP 8 Compliant age = { 'Alice': 24, 'Bob': 28, 'Ann': 26, }
So, how to correctly intend list or dictionary data enclosed in braces, brackets, and parentheses?
According to the PEP 8 standard, there are two ways to line up the closing braces, brackets, or parentheses. First, line it up with the first non-whitespace character of the previous line. Second, line it up with the first character that starts the multi-line construct.
This sounds a bit confusing so let’s hop into practical examples.
Where to Put the Closing Brace, Bracket, or Parenthesis?
For multi-line constructs, there are two basic options of how to correctly intend the data.
1. Align the closing brace with the first non-whitespace character of the previous line:
# PEP 8 Compliant age = { 'Alice': 24, 'Bob': 28, 'Ann': 26, }
2. Align the closing brace with the first character that starts the multi-line construct:
# PEP 8 Compliant age = { 'Alice': 24, 'Bob': 28, 'Ann': 26, }
Both ways of indentation are equally valid according to the PEP 8 standard. But note that in any case, the opening and closing braces (brackets, parentheses) should be placed in their own line. So the following would be a violation of the PEP 8 standard:
# NOT PEP 8 COMPLIANT age = {'Alice': 24, 'Bob': 28, 'Ann': 26, }
The reason is that both opening and closing braces (brackets, parentheses) should be placed in their own line.
However, the PEP 8 standard allows NOT to place both opening and closing braces (brackets, parentheses) into their own line—IF the arguments or items align. Here are three PEP 8 compliant examples:
# PEP 8 Compliant def f(argument_1, argument_2, argument_3, argument_4): None # PEP 8 Compliant def f(argument_1, argument_2, argument_3, argument_4): None # PEP 8 Compliant def f(argument_1, argument_2, argument_3, argument_4): None
Although the opening and closing parentheses are not placed into their own lines, it’s still PEP 8 compliant because the arguments align in the first two examples.
The following interactive code is not ready, yet. It requires your debugging superpower:
Exercise: Debug the code so that it runs. Which indentation method is your preferred one?
Why End Python List with Trailing Comma?
We’ve seen many examples of multi-line constructs where there’s a trailing comma after the last list element:
# PEP 8 Compliant age = { 'Alice': 24, 'Bob': 28, 'Ann': 26, }
The trailing comma after the last line in the dictionary ('Ann' : 26,
) is optional according to the PEP 8 standard.
Be aware: you’ll find many opinions on the web where “experts” tell you that the trailing comma is required (like here). But this is not explicitly stated in the standard. In fact, the standard recommends that you use the comma if your “items [are] expected to be extended over time” (source). In this case, it’s easier to copy&paste new items into the list (or dictionary) without having to manually add a trailing comma to the old last item and removing the trailing comma after the new last item.
In other words, the following multi-line construct is also valid and implicitly follows the PEP 8 standard:
# PEP 8 Compliant age = { 'Alice': 24, 'Bob': 28, 'Ann': 26 }
Note that the trailing comma is missing. But if you don’t plan to extend your list over time, it’s fine to use this—even if some Python code style checkers (“Linters”) complain.
Nested Multi-Line Constructs
Now, you simply need to decide about which of the above methods you prepare to write opening and closing braces, brackets, or parentheses. Here’s how you can nest those and comply with the PEP 8 standard:
# PEP 8 Compliant data = [ 'string', 42, { 1: '1', 2: '2', 42: '21', }, (1, 2, 3), ( [1, 2, 3], [4, 5, 6], ) ]
You see that we place each brace, bracket, and parenthesis in one line. The next line starts with four whitespace indentations. Then comes the item, followed by a comma. The item itself can be a multi-line construct as well. But if you understand how to write one multi-line construct, you’ll also understand how to nest them.
Similar Questions
Should curly braces appear on their own line?
Yes, they should appear on their own line. An exception is if you write the whole sequence of items in one line. In this case, the closing brace, bracket, or parenthesis should appear at the end of the same line, too.
Where to Put the Closing Brace?
As discussed previously, you line it up with the first non-whitespace character of the previous line, or with the first character that starts the multi-line construct.
Flake-8 Rule: Continuation line unaligned for hanging indent (E131)
This is a common error of the code analyzer Flake-8. A continuation line is unaligned for hanging indent.
Anti-pattern:
# NOT PEP 8 Compliant my_dict = { "key": "value", "long": "the quick brown fox jumps over the " "lazy dog", }
Best practice:
# PEP 8 Compliant my_dict = { "key": "value", "long": "the quick brown fox jumps over the " "lazy dog", }
The Art of Clean Code
Most software developers waste thousands of hours working with overly complex code. The eight core principles in The Art of Clean Coding will teach you how to write clear, maintainable code without compromising functionality. The book’s guiding principle is simplicity: reduce and simplify, then reinvest energy in the important parts to save you countless hours and ease the often onerous task of code maintenance.
- Concentrate on the important stuff with the 80/20 principle — focus on the 20% of your code that matters most
- Avoid coding in isolation: create a minimum viable product to get early feedback
- Write code cleanly and simply to eliminate clutter
- Avoid premature optimization that risks over-complicating code
- Balance your goals, capacity, and feedback to achieve the productive state of Flow
- Apply the Do One Thing Well philosophy to vastly improve functionality
- Design efficient user interfaces with the Less is More principle
- Tie your new skills together into one unifying principle: Focus
The Python-based The Art of Clean Coding is suitable for programmers at any level, with ideas presented in a language-agnostic manner.
Where to Go From Here?
Enough theory. Let’s get some practice!
Coders get paid six figures and more because they can solve problems more effectively using machine intelligence and automation.
To become more successful in coding, solve more real problems for real people. That’s how you polish the skills you really need in practice. After all, what’s the use of learning theory that nobody ever needs?
You build high-value coding skills by working on practical coding projects!
Do you want to stop learning with toy projects and focus on practical code projects that earn you money and solve real problems for people?
🚀 If your answer is YES!, consider becoming a Python freelance developer! It’s the best way of approaching the task of improving your Python skills—even if you are a complete beginner.
If you just want to learn about the freelancing opportunity, feel free to watch my free webinar “How to Build Your High-Income Skill Python” and learn how I grew my coding business online and how you can, too—from the comfort of your own home.