30 Python Language Features and Tricks You May Not Know About
30 Python Language Features and Tricks You May Not Know About
Introduction
Since I started learning Python, I decided to maintain an often visited list of "tricks". Any time I saw a piece of
code (in an example, on Stack Overflow, in open source software, etc.) that made me think "Cool! I didn't know
you could do that!" I experimented with it until I understood it and then added it to the list. This post is part of
that list, after some cleaning up. If you are an experienced Python programmer, chances are you already know
most of these, though you might still find a few that you didn't know about. If you are a C, C++ or Java
programmer who is learning Python, or just brand new to programming, then you might find quite a few of them
surprisingly useful, like I did.
Each trick or language feature is demonstrated only through examples, with no explanation. While I tried my
best to make the examples clear, some of them might still appear cryptic depending on your familiarity level.
So if something still doesn't make sense after looking at the examples, the title should be clear enough to allow
you to use Google for more information on it.
The list is very roughly ordered by difficulty, with the easier and more commonly known language features and
tricks appearing first.
April 9th, 2014 update: As you can see the article has been growing with currently 38 items in it, mostly
thanks to comments from readers. As such the number 30 in the title is no longer accurate. However, I chose
to leave it as is since that's the original title the article was shared as, making it more recognizable and easier
to find.
March 14th, 2014 update: Roy Keyes made a great suggestion of turning this article into a GitHub repository
to allow readers to make improvements or additions through pull requests. The repository is now
at https://github.com/sahands/python-by-example. Feel free to fork, add improvements or additions and submit
pull requests. I will update this page periodically with the new additions.
March 8th, 2014 update: This article generated a lot of good discussion on Reddit, Hacker News, and in the
comments below, with many readers suggesting great alternatives and improvements. I have updated the list
below to include many of the improvements suggested, and added a few new items based on suggestions that
made me have one of those "Cool! I didn't know you could do that!" moments. In particular, I did not know
about itertools.chain.from_iterable, and dictionary comprehensions. There was also a very interesting
discussion about the possibility of some of the techniques below leading to harder to debug code. My say on it
is that as far as I can see, none of the items below are inherently harder to debug. But I can definitely see how
they can be taken too far, resulting in hard to debug, maintain and understand code. Use your best judgment
and if it feels like how short and smart your code is is outweighing how readable and maintainable it is, then
break it down and simplify it. For example, I think list comprehensions can be very readable and rather easy to
debug and maintain. But a list comprehension inside another list comprehension that is then passed
to map and then to itertools.chain? Probably not the best idea!
1.1 Unpacking
>>> a, b, c = 1, 2, 3
>>> a, b, c
(1, 2, 3)
>>> a, b, c = [1, 2, 3]
>>> a, b, c
(1, 2, 3)
>>> a, b, c = (2 * i + 1 for i in range(3))
>>> a, b, c
(1, 3, 5)
>>> a, (b, c), d = [1, (2, 3), 4]
>>> a
1
>>> b
2
>>> c
3
>>> d
4
1.2 Unpacking for swapping variables
>>> a, b = 1, 2
>>> a, b = b, a
>>> a, b
(2, 1)
1.3 Extended unpacking (Python 3 only)
>>> a, *b, c = [1, 2, 3, 4, 5]
>>> a
1
>>> b
[2, 3, 4]
>>> c
5
1.4 Negative indexing
>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> a[-1]
10
>>> a[-3]
8
1.5 List slices (a[start:end])
>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> a[2:8]
[2, 3, 4, 5, 6, 7]
1.6 List slices with negative indexing
>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> a[-4:-2]
[7, 8]
1.7 List slices with step (a[start:end:step])
>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> a[::2]
[0, 2, 4, 6, 8, 10]
>>> a[::3]
[0, 3, 6, 9]
>>> a[2:8:2]
[2, 4, 6]
1.8 List slices with negative step
>>> a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
>>> a[::-1]
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> a[::-2]
[10, 8, 6, 4, 2, 0]
1.9 List slice assignment
>>> a = [1, 2, 3, 4, 5]
>>> a[2:3] = [0, 0]
>>> a
[1, 2, 0, 0, 4, 5]
>>> a[1:1] = [8, 9]
>>> a
[1, 8, 9, 2, 0, 0, 4, 5]
>>> a[1:-1] = []
>>> a
[1, 5]
1.10 Naming slices (slice(start, end, step))
>>> a = [0, 1, 2, 3, 4, 5]
>>> LASTTHREE = slice(-3, None)
>>> LASTTHREE
slice(-3, None, None)
>>> a[LASTTHREE]
[3, 4, 5]
1.11 Iterating over list index and value pairs (enumerate)
>>> a = ['Hello', 'world', '!']
>>> for i, x in enumerate(a):
... print '{}: {}'.format(i, x)
...
0: Hello
1: world
2: !
1.12 Iterating over dictionary key and value pairs (dict.iteritems)
>>> m = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
>>> for k, v in m.iteritems():
... print '{}: {}'.format(k, v)
...
a: 1
c: 3
b: 2
d: 4
Note: use dict.items in Python 3.
1.13 Zipping and unzipping lists and iterables
>>> a = [1, 2, 3]
>>> b = ['a', 'b', 'c']
>>> z = zip(a, b)
>>> z
[(1, 'a'), (2, 'b'), (3, 'c')]
>>> zip(*z)
[(1, 2, 3), ('a', 'b', 'c')]
1.14 Grouping adjacent list items using zip
>>> a = [1, 2, 3, 4, 5, 6]
>>> print_data(data)
young myope no reduced none
young myope no normal soft
young myope yes reduced none
young myope yes normal hard
young hypermetrope no reduced none
young hypermetrope no normal soft
young hypermetrope yes reduced none
young hypermetrope yes normal hard
pre-presbyopic myope no reduced none
pre-presbyopic myope no normal soft
pre-presbyopic myope yes reduced none
pre-presbyopic myope yes normal hard
pre-presbyopic hypermetrope no reduced none
pre-presbyopic hypermetrope no normal soft
pre-presbyopic hypermetrope yes reduced none
pre-presbyopic hypermetrope yes normal none
presbyopic myope no reduced none
presbyopic myope no normal none
presbyopic myope yes reduced none
presbyopic myope yes normal hard
presbyopic hypermetrope no reduced none
presbyopic hypermetrope no normal soft
presbyopic hypermetrope yes reduced none
presbyopic hypermetrope yes normal none
>>> data.sort(key=itemgetter(-1))
>>> for value, group in itertools.groupby(data, lambda r: r[-1]):
... print '-----------'
... print 'Group: ' + value
... print_data(group)
...
-----------
Group: hard
young myope yes normal hard
young hypermetrope yes normal hard
pre-presbyopic myope yes normal hard
presbyopic myope yes normal hard
-----------
Group: none
young myope no reduced none
young myope yes reduced none
young hypermetrope no reduced none
young hypermetrope yes reduced none
pre-presbyopic myope no reduced none
pre-presbyopic myope yes reduced none
pre-presbyopic hypermetrope no reduced none
pre-presbyopic hypermetrope yes reduced none
pre-presbyopic hypermetrope yes normal none
presbyopic myope no reduced none
presbyopic myope no normal none
presbyopic myope yes reduced none
presbyopic hypermetrope no reduced none
presbyopic hypermetrope yes reduced none
presbyopic hypermetrope yes normal none
-----------
Group: soft
young myope no normal soft
young hypermetrope no normal soft
pre-presbyopic myope no normal soft
pre-presbyopic hypermetrope no normal soft
presbyopic hypermetrope no normal soft
1.38 Start a static HTTP server in any directory
[10:26] $ python -m SimpleHTTPServer 5000
Serving HTTP on 0.0.0.0 port 5000 ...
1.39 Learn the Zen of Python
>>> import this
The Zen of Python, by Tim Peters