Skip to content

Python 3 will make you a better programmer.

June 6, 2008

Update: If you are interested in Python 3 you might also like my book Porting to Python 3 – An in-depth guide.

In the python-incompatibility project I’ve added loads of code that works under 2.5 but does not work under Python 3.0. I’ve also added code on how to re-write the code so that it will run under both 2.6 and 3.0.

Quite a lot of time, the rewritten code will run not only under 2.6 and 3.0, but also under 2.5! This may be surprising, but the reason is that you in 2.x is able to do a lot of bad things that you can’t do in 3.0.
One example is using the keys of a dictionary as a list. For example, this code is valid in 2.x:

d = {'key1': 'value1',
     'key2': 'value2',
     'key3': 'value3',
}
d.values()[1]

But doing that is a bad idea. The keys of a dictionary isn’t sorted, so you don’t know which one you get back. Of course, if you are going through all the keys, that’s OK, but that would mean you are doing some sort of basic newbie mistake, like

for i in len(d.keys()):
  key = d.keys()[i]

When you should be doing

for key in d.keys():

Now, in Python 3 you simply cannot slice the keys of a dictionary, because .keys() doesn’t return a list, but a view, which isn’t sliceable. So, these kinds of bad programming can’t happen in Python 3. Or, well, they can, but you need to also explicitly convert keys() to a list, so it’s unlikely you do it by mistake, which can happen under 2.5, where one person can start slicing a list without noticing that it comes from a dictionary further up in code that somebody else wrote. So in 3.0 you have to intentionally create bad code in situations where it could happen by mistake in 2.x.

I like Python 3. Python 2 rocks. Python 3 is metal!

– An in-depth guide
17 Comments
  1. I become more and more intrigued with python as time passes by!. I should really get hip with it. Google is all over it also, a huge university in my home town (stmarys.ca) is using it as thier primary language!.

    Any hewwww, i wonder what she has to say abooot it!

  2. SeeM permalink

    I think that interpreter shouldn’t prevent programmer from doing stupid things. This is not the interpreter who have brain and is thinking.
    :
    This kind of errors in code are indeed nasty and not easy to track, but can provide possibilities. In this moment I don’t remember any sensible use of dictionary very-pseudo-random sorting to prove my way of thinking, but I suppose there is really at least one.
    :
    Similar types (in this case – dicts and lists), in my very important to myself opinion, should be treated the same, as much as they can. I know that sometimes it provokes to use “magic” code, but – until programmer want it – let it does.
    :
    I know only Python, not much of other languages, and I know that high level languages are not for tricks, but to use the work of others🙂 . But sometimes I just want to program in my way and it really seems to work.
    :
    Maybe I’m worrying too much?

  3. tldr: a dictionary’s .keys() method returns a set, not a list.

  4. “I think that interpreter shouldn’t prevent programmer from doing stupid things.”

    This is not the 3.0 interpreter “preventing stupid things”. This is the 2.5 interpreter enabling stupid things, and them fixing the 3.0 interpreter to stop enabling stupid things.

    There are no useful possibilities that this provides that can’t be obtained by explicitly saying “give me the list”, and there are bugs that can be hidden by doing it the 2.5 way.

    Python is actually way ahead on the “treat similar types as similarly as possible” front (the sequence protocol is a huge win), but you do not win when the abstraction is raised so high that the actual differences are elided.

  5. Lennart, you are clearly a Zope/Plone expert. I have been seeing your name on the mailing lists and elsewhere for years.

    I was just wondering why you run this blog in WordPress. If you did it in Plone then others could be impressed by it and copy its features.

  6. Mozey: Yup, Python really is a very good language to know.

    SeeM: It’s not the interpreter, it’s the language. And languages should stop you from doing stupid things, at least unless you explicitly say that you want stupidity. And no, I really don’t think there is one sensible use of slicing dict.keys().

    Dicts and lists are not similar types. And no, you are not worrying to much. The point is, you can still program your way in Python 3. Python 3 doesn’t prevent you from doing things your way. It just that a lot of bad code gets harder to do. And I don’t think bad code is “your way”.🙂

  7. ddasilva:
    >>> type({1:2}.keys())

    Jonathan: I’m not interested in hosting my own blog, that would be a huge waste of time for me, and WordPress out-features anything in the Zope world. Quills is useable, but it is a software for those who want a blog in the Plone site, not something you would use if you want a dedicated blog.

  8. bearophile permalink

    In Python 2.5 this is much better (avoids the creation of a list):
    for key in d:

  9. Carl permalink

    I think for key in d: is superior to for key in d.keys(): 99% of the time.

  10. Minor point:

    for key in d.keys()

    is not necessary. You can simply do:

    for key in d:

  11. Bearophile, Carl, David: Yes, you are all correct, maybe I should have used dict.values() as the example instead.🙂

  12. steve j permalink

    Nice tweak for when a duck is not quite a duck:
    “so it’s unlikely you[…]start slicing a list without noticing that it comes from a dictionary further up in code that somebody else wrote.”
    Cool observation, thanks.

  13. Here is free access to the rough cut version of Mark Summerfield’s “Programming in Python 3: A Complete Introduction to the Python Language.” Here Summerfield explains the structure and approach of his book and shows you how to install Python.
    This chapter is from the Rough Cut version of the book.
    http://www.informit.com/articles/article.aspx?p=1271258

  14. Ooh, spam! Well, OK, I’ll admit it this time, then.😉

  15. tom oconnell permalink

    This all great, but why did you remove the normal function of looking up a value
    through the key?
    the following no longer works

    if(d.has_key(“key”))
    This has nothing to do with depending on anything other that
    being able to look of a key. Now i have code that will not fit in python or python3.
    Wonderful

    • 1. “d.has_key(k)” has been discouraged since December 2001, when 2.2 was released. Instead you should use “k in d”.
      2. 2to3 will convert all your “d.has_key(k)” into “k in d” without problems, so this is not an issue. This will work fine under Python 3.
      3. *I* didn’t remove anything.🙂

Trackbacks & Pingbacks

  1. Programming Day 1: The setup | B1naryTh1ef's Blog

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: