When I’m looking at questions asked on sites like stackoverflow on how to make a particular piece of code “more pythonic” there are usually suggestions offered to use complex list comprehensions or generators or other python features that aren’t available in, say, Java.
I am a casual Python programmer, and sometimes I can’t follow what’s going on without carefully unwrapping the logic in my head. Sometimes the list comprehensions are nested in ways that I’m thinking “you probably should just write it out using loops”.
Of course, veteran Python users probably won’t have an issue with this, but I’m increasingly getting the impression that “pythonic code” is preferred over writing code that would be readable for the “average programmer” that may not be very proficient in Python.
In general, what are some guidelines and heuristics to follow when choosing between the readability of the code and following the conventions used in a specific programming language community?
6
Sometimes the list comprehensions are nested in ways that I’m thinking “you probably should just write it out using loops”.
If you would refactor the code really that way, it would most probably lead to a replacement of one evil by another. IMHO it is better not to replace too deeply nested list comprehensions by (still too deeply nested) loops. Instead, replace too deeply nested lists comprehensions by not so deeply nested list comprehensions. This gives you a chance to add “explaining variables” with clear names for intermediate results, and you can still think in “sets”, which produces much less “noise” than loops, and is still “pythonic”.
If you’re ‘carefully unwrapping the logic’ to make sense of a line of code, the author missed the boat on being Pythonic. Being Pythonic isn’t about using obscure language features to pack as much code as possible into a line – that’s what Perl’s for. Being Pythonic is about keeping code simple, readable and efficient.
>>> import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren’t special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one– and preferably only one –obvious way to do it.
Although that way may not be obvious at first unless you’re Dutch.
Now is better than never.
Although never is often better than right now.
If the implementation is hard to explain, it’s a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea — let’s do more of those!
7
If you can’t read it, you can’t debug it or maintain it.
‘more Pythonic’ code that you can’t maintain is worthless, so for you, using the more complex features is a bad idea, no matter how elegant the answer is in terms of the language.