Python Tricks: Complacent Comma Placement
Here’s a handy tip for when you’re adding and removing items from a list, dict, or set constant in Python:Just end all of your lines with a comma.
Not sure what I’m talking about? Let me give you a quick example. Imagine you’ve got this list of names in your code"
>>> names = ['Alice', 'bob', 'Dilbert']
Whenever you make a change to this list of names, it’ll be hard to tell what was modified by looking at a Git diff, for example, Most source control systems are line-based and have a hard time highlighting multiple changes to a single line.
A quick fix for that is to adopt a code style where you spread out list, dict, or set constants across multiple lines, like so:
>>> names = [
... 'Alice',
... 'Bob',
... 'Dilbert'
... ]
That way there’s one item per line, making it perfectly clear which one was added, removed, or modified when you view a diff in your source control system. It’s a small change but I found it helped me avoid silly mistakes. It also made it easier for my teammates to review my code changes.
Now, there are two editing cases that can still cause some confusion. Whenever you add a new item at the end of a list, or you remove the last item, you’ll have to update the comma placement manually to get consistent formatting.
Let’s say you’d like to add another name(Jane) to that list. If you add Jane, you’ll need to fix the comma placement after the Dilbert line to avoid a nasty error:
>>> names = [
... 'Alice',
... 'Bob',
... 'Dilbert' # <- Missing comma!
... 'Jane'
]
When you inspect the contents of that list, brace yourself for a surprise:
>>> names
['Alice', 'Bob', 'DilbertJane']
As you can see, Python merged teh strings Dilbert and Jane into DilbertJane. This so-called “string literal concatenation” is intentional and documented behavior. And it’s also a fantastic way to shoot yourself in the foot by introducing hard-to catch bugs into your programs:
“Multiple adjacent string or bytes literals(delimited by whitespace),possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation”
Still, string literal concatenation is a useful feature in some cases. For example, you can use it to reduce the number of backslashes needed to split long string constants across multiple lines:
>>> My_str = ('This is a super long string constant '
... 'spread out across multiple lines.'
... 'And look, no backslash characters needed!')
On the other hand, we’ve just seen how the same feature can quickly turn into a liability. Now, how do we fix this situation?
Adding the missing comma after Dilbert prevents the two strings from getting merged into one:
>>> names = [
... 'Alice',
... 'Bob',
... 'Dilbert',
... 'Jane'
... ]
But now we’ve come full circle and returned to the original problem. I had to modify two lines in order to add a new name to the list. This makes it harder to see what was modified in the Git diff again… Did someone add a new name? Did someone change Dilbert’s name?
Luckily, Python’s syntax allows for some leeway to solve this comma placement issue once and for all. You just need to train yourself to adopt a code style that avoids it in the first place. Let me show you how.
In Python, you can place a comma after every item in a list, dict, or set constant, including the last item. That way, you can just remember to always end your lines with a comma and thus avoid the comma placement juggling that would otherwise be required.
note: Python Docs:“String literal concatenation”