Pythonic

Tuesday 2 November 2010This is nearly 14 years old. Be careful.

A nice question on Stack Overflow today drew good answers, but one of them chided,

Stop saying “pythonic” when you mean “clean”. It’s just a cheesy buzzword.

It made me think about what people mean by “pythonic,” I think it is more than simply “clean.” I think it also involves appropriate use of the language and standard library features. It of course includes “clean” but I think you can write clean Java-like code in Python, and it will not be pythonic. The pythonic label has to do with a minimalism, getting more done than seems possible with a small amount of code.

But I also wonder, why does Python have an adjective, when other languages do not? We don’t hear about code being Javanese, or Pearly, or Rubinesque. Why don’t we speak of code that is C-plush-plush, or PHPleasing? Why does Python have an adjective?

PS: any other interesting proposals for language adjectives?

Comments

[gravatar]
I have always viewed "pythonic" as doing something as Guido would have done it, i.e., using the language to its fullest as designed. This is why I claim that something is only as pythonic as Guido says it is and thus you can't argue with him about it. =)
[gravatar]
Because Python, unlike most languages, has a strong *design aesthetic*. Python is the Apple of programming languages.

It's impossible for certain languages on your list to have a design aesthetic. PHP and Java are too clunky. Also consider that Perl (and to some extent Ruby) would *value* the lack of a strong aesthetic. The presence of many ways to do things coupled with the lack of a clear best way is a postmodern virtue.
[gravatar]
Fortesque.
[gravatar]
I am, form now, on going to refer to all proper Ruby code as Rubinesque!

@Brett please for the love of... no WWGD stickers.....
[gravatar]
In Russia we have sentence "Java of the brain", but this mean something contraversal to pythonic.
[gravatar]
From the moment I've encountered the word, I've never thought of Pythonic as being synonymous with "clean". While generally a fairly permissive language, Python clearly steers you towards its preferred idioms.

It's also interesting that what is Pythonic has changed as Python has matured---Python 3 is the latest iteration in this process as the old idioms have been dropped for what is the modern core of the language.

I would have liked to have seen even more of the standard library cleaned up as part of Python 3. A lot of the modules from the 1.x days don't feel very pythonic to me. Still, Python 3 shipped and it might still be in development if they tried to do all that too.
[gravatar]
Perl does have the concept if not a popular name. perlmonks.com is a long standing (10+ years) place where perl users go to share tips and have their code critiqued by other perl users. They even have a "karma" system for rating commenters (I'm still rated as a "Monk" from my pre-python days).
[gravatar]
Maybe because "Pythonic" sounds good. In other languages this is called idiomatic.
[gravatar]
+1 for idiomatic
[gravatar]
...because Javanese, Pearly and especially PHPleasing are usually synonyms of ugly.
[gravatar]
Remember the Zen of Python? "There should be one-- and preferably only one --obvious way to do it."

That's how I'd define the Pythonic way of writing code. You know it when you see it.
[gravatar]
hmmmm, Maybe it's not bad to use "pythonic" as "clean" meaning. We can use "True Pythonic" if we insist on that "I think it also involves appropriate use of the language and standard library features." ... maybe! :D
[gravatar]
You can code anything with variable assignment, function definitions, if statements and "for i in range(n)", i.e., using only a handful of commands common to any programming language. You can code absolutely anything you like with those few commands.

Python offers however a wide range of improvements over those basic commands: list comprehensions, named arguments, default arguments, "for elt in some_list", dictionaries, generators, and so on.

To me, being pythonic is to use that range of Python improvement vs programming in a dull way as in any other language.

Examples:

"for i in range(len(L)): print L[i]" -> not pythonic. "for elt inL: print elt" -> pythonic.

"L[len(L)-1]"-> not pythonic. "L[-1]"->pythonic.
[gravatar]
How about Perlish? Lispy?
[gravatar]
I've never seen it used this way, but "Clojuresque" could mean "idiomatic Clojure".
[gravatar]
"Pythonic code" is shorter than "idiomatic Python code", so I think I'll continue using it.
[gravatar]
I've heard "ajaxy" used quite a bit
[gravatar]
I don't think you'd want to call Ruby code Rubinesque because it's a homophone (and one letter off of a homonym) for Rubenesque, which is used to describe the art of Rubens who was rather famous for painting plump women. And, while I've nothing against plump women I'm not thinking that it's really an association you want to make with Ruby code.
[gravatar]
Thanks all for the thoughts, very interesting.

@brett: as much as I would like to say that Guido doesn't always win "is it pythonic" debates, I have a feeling he probably always does!

@nickf: "ajaxy" reminds me of "enterprisey", there are probably more language-agnostic adjectives of their ilk.

@masukomi: I was intentionally using the existing adjective (inadvertently misspelled!) not because Ruby code is plump, but because it's such a great adjective to begin with!
[gravatar]
I do hear people say "Perlesque" every now and then, but I think it's mostly used in a derogatory manner...
[gravatar]
Python is proud of having "only one way to do it". I think "Pythonic" means finding that one way.
[gravatar]
Because what is 'clean' in some other language can usually be made even more so in python. Succinctly put.
[gravatar]
Maybe there's no "Rubyesque", but twenty years ago we did talk about code being more or less "FORTHy".
[gravatar]
As for why other languages don't have an adjective:

Java all looks the same, so there's no need for one.

Good C++ is whatever adheres to whatever coding standard you happen to be using. I'm not sure you can get much more consensus than that.

Perl and Ruby are too all over the place (TIMTOWTDI), so using a supposed adjective might actually be considered insulting or at least impolite in those communities. (i.e. there is no such thing as "idiomatic" Perl/Ruby)

There is however idiomatic Rails code, so I guess you could refer to something as "Rails-ish".

So few people in the PHP community know what good code should look like I doubt anyone could agree on what PHPleasing would mean.

I almost went so far as to say that there is no such thing as good code in PHP, but I stopped myself. There is some, but so little in proportion to all the garbage out there that it's hard to remember sometimes...
[gravatar]
Pythonic is in Wikipedia, and the explanation is well enough

You problably know that Python has PEP.
Ok, Now, read PEP 8

"here are the Pythonic guidelines:"...


Do you know a language with a similar "open" feature ?, if yes, you should probably create adjective, verb or what you want with. Otherwhise, just pythonize your code :-)
[gravatar]
What has always surprised me about the term "pythonic" is that this was the adjectival word chosen.

Python is named after Monty Python. Monty Python inspired the adjective "pythonesque" which made it into dictionaries years ago.

Yet the programmers generally prefer "pythonic" over "pythonesque" when referring to the code. That's odd to me.
[gravatar]
Pythonic simply means idiomatic python. The same expression works for any language.
[gravatar]
Pythonic isn't just idiomatic Python -- it's tasteful Python. It's less an objective property of code, more a compliment bestowed onto especially nice Python code. The reason Pythonistas have their own word for this is because Python is a language that encourages good taste; Python programmers with poor taste tend to write un-Pythonic code.

This is highly subjective, but can be easily understood by Pythonistas who have been with the language for awhile.

Here's some un-Pythonic code:
def xform(item):
    data = {}
    data["title"] = item["title"].encode("utf-8", "ignore")
    data["summary"] = item["summary"].encode("utf-8", "ignore")
    return data
This code is both un-Pythonic and unidiomatic. There's some code duplication which can very easily be factored out. The programmer hasn't used concise, readability-enhancing facilities that are available to him by the language. Even lazy programmers will recognize this code's clear downsides.

Here's another version that is more idiomatic but is nonetheless still un-Pythonic:
class ItemTransformer(object):
    def __init__(self, item):
        self.item = item

    def encode(self, key):
        return self.item[key].encode("utf-8", "ignore")

    def transform(self):
        return dict(
            title=self.encode("title"), 
            summary=self.encode("summary"))
Nothing about this code is particularly unidiomatic. I might even see code like this in many popular open source projects. But it's in poor taste. It's un-Pythonic.

What is the code doing? It's just taking an incoming dictionary, encoding its values using utf-8, and returning a new dictionary with those encoded values. There is no need to introduce an ItemTransformer object -- it's an extra abstraction and is just making the signal-to-noise ratio poorer. People coming from Java often write un-Pythonic code because Java is a language that does not reward good taste. The Pythonic view is: programming is hard enough -- let's not make it harder for ourselves.

Here's a more Pythonic version:
def encode_news_item(item):
    def encoded(*keys):
        for key in keys: 
            yield (key, item[key].encode("utf-8", "ignore"))
    return dict(encoded("title", "summary"))
This code shows comfort with Python's features, but does not abuse this comfort by obfuscating the code with mind-bending constructions. The programmer has reduced the problem to two comprehensible subproblems: creating a stream of tuples (key, encoded_value) and constructing the new dictionary from that stream. This leverages the elegant fact that in Python, dictionaries can be easily constructed from (key, value) tuples.

This version avoids code duplication while also making the last line (the return statement) a rough description of the entire function. "return a dictionary of the encoded values for the keys title and summary" Idiomatic, yes. But also tasteful, and thus Pythonic.

Even Pythonic code can be improved:
def encode_news_item(item):
    encoded = lambda key: item[key].encode("utf-8", "ignore")
    keys = ("title", "summary")
    return dict((key, encoded(key)) for key in keys)
And though Pythonic code is often smaller than its un-Pythonic counterparts, the experienced Pythonista knows the road to hell is paved with good intentions:
def encode_news_item(item):
    keys = ("title", "summary")
    return dict(zip(keys, map(lambda key: item[key].encode("utf-8", "ignore"), keys)))
Ick... time to hg revert this idiomatic Python code to the more Pythonic version ;-)
[gravatar]
Pythonic, the word; has a useful effect within the Python community of focussing new entrants on code quality.

The Python community thinks about quality enough to have its own word for it.
[gravatar]
Fortrani, Tclish, Pascallic, Modular, Rubinous, Forthicious.
[gravatar]
Would Tclish be pronounced ticklish? That made me smile (as did C-plush-plush), thanks. I also came up with awkward, but that's wrong.
[gravatar]
Chris McDonough 12:41 PM on 4 Nov 2010
Although "pythonic" may have some value, "unpythonic" used as a criticism of code has about as much concrete value as "unamerican", and is often used about as gracefully.
[gravatar]
I was a "Saint" on Perlmonks back in the day (before they readjusted the XP levels; now my long abandoned account is just a "Prior") and I can confirm that there is definitely an equivalent concept in the Perl community. It pretty much comes down to code being idiomatic and elegant. The way I always thought about it was that it was sort of the opposite of how you can "write C in any language". So with Python if, instead of writing Java in Python, you write Python in Python, it's "Pythonic".
[gravatar]
Luatic.

Groovy, of course, is its own adjective.
[gravatar]
i live in java island. javanese is my native language

:)
[gravatar]
"Pythonic" is insiders jargon for a particular coding style. I find it particularly unhelpful to use it in a criticism as the author of the code likely doesn't know the word or has a different interpretation of it. Much better to explain why you do or don't like the way a piece of code works - exactly as Andrew Montalenti did above :)
[gravatar]
Somewhat idiosyncratically, I use 'Rubyonic' to describe code that provides a magical-feeling and intuitive interface.

@Andrew Montalenti:

The Pythonic version of
def encode_news_item(item):
    encoded = lambda key: item[key].encode("utf-8", "ignore")
    keys = ("title", "summary")
    return dict((key, encoded(key)) for key in keys)
would be
def encode_news_item(item):
    return { 
        key: item[key].encode("utf-8", 'ignore')
            for key in ('title', 'summary')
    }
[gravatar]
@katmagic, that is "Py3Konic". Doesn't work in 2.x. But I agree that dictionary comprehensions are nice ;-)
[gravatar]
Check out pythonic on google ngram viewer, there are plenty of references in 1800s...

The meaning was different though ;-)
[gravatar]
I can confirm that there is definitely an equivalent concept in the Perl community. It pretty much comes down to code being idiomatic and elegant.

Add a comment:

Ignore this:
Leave this empty:
Name is required. Either email or web are required. Email won't be displayed and I won't spam you. Your web site won't be indexed by search engines.
Don't put anything here:
Leave this empty:
Comment text is Markdown.