I've been using Python for a few years now, and continue to love it. But the language is large enough that it seems every project that I look at uses a different subset of the language's features. The nice thing is that by reading different people's code, you can find out about some real gems in the Python programming language. Some of these tips are extremely obvious, and some are more obscure. In any case, here are what I consider to be some real gems:
filter This is one of Python's built-in functions, which allows you to remove unwanted items from a list. It's very useful and highly overlooked. Here's an example of how to use it:
>>> lst = ['1', '2', '3', '4', 'asdf', '5'] >>> def is_int_string(i): ... try: ... int(i) ... return True ... except ValueError: ... return False ... >>> int_string_list = filter(is_int_string, lst) >>> int_string_list ['1', '2', '3', '4', '5']
But there is a really neat filter shortcut, too. You can have it filter out any values which evaluate to False.
>>> lst = [0, 2, '', 'asdf', None, [], (), 'fdsa'] >>> filter(None, lst) [2, 'asdf', 'fdsa']
This is really great for filtering out unwanted values in a list. I use it actually quite frequently and hope to see it in more python projects.
itertools.chain I often have a list of lists, and want to run some operation on each item in that list of lists. itertools.chain allows that to happen. Let me demonstrate with an example:
>>> import itertools >>> lst = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] >>> list(itertools.chain(*lst)) [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> sum(itertools.chain(*lst)) 45
itertools.chain has become a major part of my day-to-day coding toolbox, and it's a real python gem.
setdefault Do you find yourself writing this type of try..except KeyError pattern often?
>>> dct = {} >>> items = ['anne', 'david', 'kevin', 'eric', 'anthony', 'andrew'] ... for name in items: ... try: ... dct[name[0]].append(name) ... except KeyError: ... dct[name[0]] = [name] >>> dct {'a': ['anne', 'anthony', 'andrew'], 'k': ['kevin'], 'e': ['eric'], 'd': ['david']}
That's a lot of boilerplate code for something that seems like it should be much easier. Thankfully, this can be solved much more easily by using setdefault, like so:
>>> dct = {} >>> items = ['anne', 'david', 'kevin', 'eric', 'anthony', 'andrew'] >>> for name in items: ... dct.setdefault(name[0], []).append(name) ... >>> dct {'a': ['anne', 'anthony', 'andrew'], 'k': ['kevin'], 'e': ['eric'], 'd': ['david']}
Much better, isn't it?
defaultdict Given setdefault, it still seems like there should be a better way. If you know upfront that you will be setting everything to an empty list if it isn't found, you should be able to specify that and have it just Do The Right Thing. Thankfully, defaultdict does just that:
>>> from collections import defaultdict >>> dct = defaultdict(list) >>> items = ['anne', 'david', 'kevin', 'eric', 'anthony', 'andrew'] >>> for name in items: ... dct[name[0]].append(name) ... >>> dct defaultdict(<type 'list'>, {'a': ['anne', 'anthony', 'andrew'], 'k': ['kevin'], 'e': ['eric'], 'd': ['david']}) >>> dict(dct) {'a': ['anne', 'anthony', 'andrew'], 'k': ['kevin'], 'e': ['eric'], 'd': ['david']}
I usually end up converting the defaultdict back to a regular dict before passing it around, but other than that, it's quite a useful tool to use.
zip This is one that most people usually know, but still I find that sometimes people do strange things where a zip would be much easier.
>>> numbers = [1, 2, 3, 4, 5] >>> letters = ['a', 'b', 'c', 'd', 'e'] >>> for num, let in zip(numbers, letters): ... print "Letter %d is '%s'" % (num, let) ... Letter 1 is 'a' Letter 2 is 'b' Letter 3 is 'c' Letter 4 is 'd' Letter 5 is 'e'
Pretty simple, very common, and yet sometimes coders seem to work around it. Also worth mentioning is that there's an iterable version of this, izip, which is located in itertools.
title I wrote some little function to turn a string of lower case text into a 'titleized' string at work, and a few coworkers laughed and said, "why didn't you just use title"? The answer: I didn't know about it. It's not something you run into every day, but when you need it, it's super useful. Here's an example:
>>> s = 'the little green men' >>> s.title() 'The Little Green Men'
It's that easy! Next time you need to turn something into a title, look for this method on strings first.
That's all I've got for now. There are many more gems in the Python programming language, but these are some that I think are especially useful. Please share in the comments if you have any other gems that you have found in your uses of Python.
UPDATE: Eric Holscher has posted a list of his Python gems as well, and it's got some great stuff on it. Check it out!
All Content


By Gabriel at 10:01 p.m. on Nov. 2, 2008
Great list! filter might be a bit contentious as Guido has tried to remove it in python 3k:
http://www.artima.com/weblogs/viewpost.jsp?thread=98196
I am torn as I find the list comprehension filter a little verbose . . .
filter(is_int_string, lst)
vs
[x for x in lst if is_int_string(x)]
By Gabriel at 10:03 p.m. on Nov. 2, 2008
Whoops! Forgot to add a gem I use a lot. I often deal with lists of lists, spreadsheet like data structures and I find the use of zip(*spreadsheet) to be a really cool way of transposing the rows and columns!
By jwhitlark at 1:44 a.m. on Nov. 3, 2008
Whoa. I love that one. Wish I had seen it for my cookbook entry!
By enumerate at 1:42 a.m. on Nov. 3, 2008
enumerate is a gem
By James Tauber at 3:10 a.m. on Nov. 3, 2008
defaultdict is definitely cool. One thing you didn't mention is the argument to defaultdict is a callable for constructing the default item. I often use defaultdict(int) for counting objects as you can just say counts[key] += 1
By Russell at 3:33 a.m. on Nov. 3, 2008
Thanks for these. These are mainly functional programming aspects of Python. Do you work in any functional languages like Scheme or Erlang? These constructs (zip, filter, fold etc) are the primary tools of those languages.
By Thomas Guest at 4:10 a.m. on Nov. 3, 2008
As another useful form of dict initialisation, you could recast 4 as:
dct = dict((name[0], name) for name in 'anne david kevin eric anthony andrew'.split())
By Thomas Guest at 4:15 a.m. on Nov. 3, 2008
Silly me. Scratch that last comment! It's not the same as 4 at all (though it is a useful way to initialise a dict).
By Thomas Guest at 4:28 a.m. on Nov. 3, 2008
Here's what I was thinking of. For 4, you *could* have.
>>> from itertools import groupby
>>> from operator import itemgetter
>>> first = itemgetter(0)
>>> dct = dict((k, list(v)) for k, v in groupby(sorted(items, key=first), first))
Definitely not recommended. A defaultdict is simpler and avoids unnecessary sorting.
By Michael Kuhn at 6 a.m. on Nov. 3, 2008
+1 for enumerate
I used defaultdicts a lot, but they can bite you if you inadvertently create entries and then later rely on all entries being valid.
By eric casteleijn at 6:03 a.m. on Nov. 3, 2008
I actually *hate* title: It's a convenience method that is almost never needed, and it does the wrong thing for exactly 100% of the languages I know:
Title casing in english should leave the articles and (short) prepositions lowercase.
Title casing in dutch (and most other european languages) is just capitalizing the first word of the title.
As it's seldom used, and trivial to implement, and potentially confusing if you don't know it's there. (In my very early python days I ran into this, when my code expected an object with a .title, but got a string, and didn't break in the place I expected it to.)
By Beetle B. at 8:49 a.m. on Nov. 3, 2008
+1 for enumerate. I use it heavily to avoid index arithmetic in loops. Sometimes you *have* to know the index, but don't want to keep track of it.
Another cool trick: See
http://thraxil.org/users/anders/posts/2007/10/30/A-Simple-Programming-Puzzle-Seen-Through-Three-Different-Lenses/
It may be easier to understand if you look at the Haskell version he links to.
By Ken at 10:20 a.m. on Nov. 3, 2008
Gabriel: "I am torn as I find the list comprehension filter a little verbose"
Guido: "filter(P, S) is almost always written clearer as [x for x in S if P(x)]"
I agree with Guido that filter(P,S) is hard to read, but not that a list comprehension is the easiest way to read it. My problem is simply that "filter" as a word doesn't read very well, and this really sticks out in Python which otherwise can read *very* well.
Common Lisp calls it "remove-if" and "remove-if-not", which sound perfectly natural to me: (remove-if-not 'is-int-string '("1" "2" "3" "4" "asdf" "5")). I guess the word "filter" comes from Haskell, which is a neat language, but maybe not the easiest to scan unless your brain is in mathematician-mode.
By stroky.l at 10:58 a.m. on Nov. 3, 2008
nice !!!
By dublpaws at 12:36 p.m. on Nov. 3, 2008
the predicate is_int_string, is included with the str type, so... filter(str.isdigit, seq)
By digits at 1 p.m. on Nov. 3, 2008
"-34" parses as an int but fails the isdigit test.
By Matthew at 1:08 p.m. on Nov. 3, 2008
I'm a Haskell hacker, and I find it interesting that the basic plumbing functions (chain, zip, filter) are basic Haskell functions (though chain would be called concat in Haskell.)
I love python for bringing FP into the mainstream.
By anon_coward at 3:05 p.m. on Nov. 3, 2008
http://mail.python.org/pipermail/python-dev/2006-February/061261.html in which GvR sums up on a _long_ thread on defaultdict (the thread goes on for quite a while thereafter)
By Dr. Drang at 4 p.m. on Nov. 3, 2008
Another problem with title() is that it doesn't understand apostrophes, I just learned last week:
http://www.leancrew.com/all-this/2008/10/song-versions-in-itunes/
"Baby please don't go".title() becomes "Baby Please Don'T Go", probably not what you had in mind.
By Nathan at 6:24 p.m. on Nov. 3, 2008
It doesn't give you an iterator, but a shorter way for chaining a list of lists I've come to like is sum(lst, [])
By digits at 10:03 p.m. on Nov. 3, 2008
That only works if they are actual lists (or at least some sort of sequence overloading the addition operator for concatentation). itertools.chain can take arbitrary iterables.
By blaine at 8:06 a.m. on Nov. 5, 2008
thanks for the article mang. defaultdict is a lifesaver. for my machine learning class i'm doing a lot of 'count the frequency this value occurs in the data set'. there is a lot of this business going on:
try: d[val] += 1
except KeyError: d[val] = 0
its a lot cleaner with default dict. thanks!
By wow power leveling at 7:21 p.m. on Nov. 7, 2008
I'm glad to hear it! Shoot me an e-mail if you have any problems.
By Beorn at 3:58 p.m. on Nov. 20, 2008
It's sad that lambda is so rarely used, especially that it fits well in combination with functions such as map() or filter(). Example for fetching small sets of data from database and returning it as some class instances:
class SomeClass(object):
def __init__(self, a, b, c):
...
...
cursor.execute("""SELECT a, b, c FROM d""")
result = map(lambda x: SomeClass(*x), cur.fetchall())
By wholesale jewelry at 12:33 a.m. on May 4, 2009
This site is so helpful and useful.thks/
By yaling at 1:51 a.m. on May 11, 2009
<A href="http://www.china-jewelry-market.com"> Jewelry Market</A>
<A href="http://www.korean-jewelry.com">Korean Jewelry </A>
By Wholesale lingerie at 9:21 p.m. on May 15, 2009
That only works if they are actual lists (or at least some sort of sequence overloading the addition operator for concatentation). itertools.chain can take arbitrary iterables.
By ben10 oyunları at 2:56 a.m. on May 25, 2009
As it's seldom used, and trivial to implement, and potentially confusing if you don't know it's there. (In my very early python days I ran into this, when my code expected an object with a .title, but got a string, and didn't break in the place I expected it to.)
By cheap chanel handbags at 11:32 p.m. on May 26, 2009
so good , it is cool
By cheap nike shoes at 12:15 a.m. on May 27, 2009
many people will like it
By wholesale nike shoes at 12:16 a.m. on May 27, 2009
let me bookamr you
By cheap jordans at 12:16 a.m. on May 27, 2009
so pity
By taylormade r7 at 12:21 a.m. on May 27, 2009
hope you can good
By D3 at 7:26 p.m. on May 27, 2009
defaultdict is definitely cool. One thing you didn't mention is the argument to defaultdict is a callable for constructing the default item.
By club penguin at 9:26 p.m. on May 31, 2009
I agree with Guido that filter is hard to read, but not that a list comprehension is the easiest way to read it.
My problem is simply that "filter" as a word doesn't read very well, and this really sticks out in Python which otherwise can read very well.
By wholesale jewelry at 1:04 a.m. on June 4, 2009
Nice post,good website,it is great
By Ways to Make Money Online at 12:09 a.m. on June 9, 2009
Thanks, this was really resourceful for my computer.
By lingeriewholesale at 9:51 a.m. on June 9, 2009
Guido that filter(P,S) is hard to read, but not that a list comprehension is the easiest way to read it. My problem is simply that "filter" as a word doesn't read very well, and http://www.dear-lover.com/ this really sticks out in Python which otherwise can read *very* well.
Common Lisp calls it "remove-if" and "remove-if-not", which sound perfectly natural to me:
By Social Work Degree at 1:21 a.m. on June 10, 2009
hope you can good
By Sociology Masters Degree at 1:22 a.m. on June 10, 2009
Nice post,good website,it is great
By Online History Graduate Degree at 1:22 a.m. on June 10, 2009
so good , it is cool
By wholesale jewelry at 8:26 p.m. on June 10, 2009
Good website,nice post.
By wow power leveling at 4:46 a.m. on June 13, 2009
What you said is really right, I agree with you.
By nan at 1:49 p.m. on June 13, 2009
nice :)
By injection molding at 9:24 p.m. on June 13, 2009
nice blog! Really worth reading!!!
By Homeschool online at 6:14 a.m. on June 16, 2009
Information is truly extraordinary, I am very interested to read this post.
By Online High School at 6:14 a.m. on June 16, 2009
This is really a great stuff for sharing.keep it up .Thanks for sharing,
By casino online at 7:17 p.m. on June 22, 2009
welcome to play
By cool at 10:16 p.m. on June 22, 2009
so good , it is cool
http://www.mpos.net/s/p3.asp
By enterprise car rental satellite radio at 8:03 a.m. on June 23, 2009
nice blog! Really worth reading!!!
By best waterproof digital camera 2009 at 8:05 a.m. on June 23, 2009
defaultdict is definitely cool. One thing you didn't mention is the argument to defaultdict is a callable for constructing the default item.
By floor jack replacement parts at 8:06 a.m. on June 23, 2009
Whoa. I love that one. Wish I had seen it for my cookbook entry!
By Vistaprint Discount at 8:02 p.m. on June 23, 2009
absolutely makes sense. I like this post, it is great. well done all.
By fashion costume jewelry at 3:03 a.m. on June 24, 2009
thanks for share
<A href="http://www.china-costume-jewelry.com">costume jewelry</A>
<A href="http://www.chinafashionjewelrywholesale.com">Wholesale fashion Jewelry</A>
By jewelry at 10:21 p.m. on June 26, 2009
jewelry wholesale,sin jewelry company,http://www.jewelry86.com
By jewelry wholesale at 10:24 p.m. on June 26, 2009
silver jewelry jewelry wholesale
http://www.jewelry86.com
By nilson Jack at 12:44 a.m. on July 1, 2009
thanks post...
http://www.abercrombieonsale.com/
http://www.edhardyshop.us
http://www.edhardyuk.co.uk
http://www.lowratemortgagetoday.com/
By Stop Dreaming Start Action at 7:03 a.m. on July 2, 2009
this is very interesting. thanks for that. we need more sites like this. i commend you on your great content and excellent topic choices. i'm spreading the good word about this site to all
By Rusli Zainal Sang Visioner at 7:03 a.m. on July 2, 2009
Thanks for sharing this great article! That is very interesting Smile I love reading and I am always searching for informative information like this
By Salvia at 9:50 a.m. on July 2, 2009
How are you. We are made to persist. That's how we find out who we are.
I am from Yemen and learning to write in English, please tell me right I wrote the following sentence: "Herbal cream soothes discomfort from flea bites."
Thank you so much for your future answers :-D. Salvia.
By khazn at 6:40 a.m. on July 3, 2009
good .... :$
Thank you