21 May 2012

From Lyon

Tag: Python

Python built-in functions are awesome. Use them!

Written by Balthazar

Introduction

In this article, we are going to see a couple use-case examples of some of the Python built-in functions. These functions can prove themselves extremely useful, and I think every Python coder should learn how to use them: they’re fast and well thought.

For each function, I will provide two snippets: one without any built-in function, and the equivalent “pythonic” snippet.

Do not get offended by the fact that I might copy and paste function description from the built-in functions documentation, these guys are better than me at writing documentation!

all(iterable)

Return True if all elements of the iterable are true (or if the iterable is empty).

_all = True
for item in iterable:
    if not item:
        _all = False
        break
if _all:
    # do stuff

This snippet is equivalent to :

if all(iterable):
    # do stuff

any(iterable)

Return True if any element of the iterable is true. If the iterable is empty, return False.

_any = False
for item in iterable:
    if item:
        _any = True
        break
if _any:
    # do stuff

This snippet is equivalent to :

if any(iterable):
    # do stuff

cmp(x,y)

Compare the two objects x and y and return an integer according to the outcome. The return value is negative if x < y, zero if x == y and strictly positive if x > y.

So if you implemented a function looking like that:

def compare(x,y):
    if x < y:
        return -1
    elif x == y:
        return 0
    else:
        return 1

Well folks… That’s just exactly what cmp(x,y) does.

dict([arg])

Create a new data dictionary, optionally with items taken from arg.

This arg part is usually unknown, but it’s extremely convenient! For example, if we had a list of 2-tuples that we’d like to convert to a dict, we could do that:

l = [('Knights', 'Ni'), ('Monty', 'Python'), ('SPAM', 'SPAAAM')]
d = dict()
for tuple in l:
    d[tuple[0]] = tuple[1]
# {'Knights': 'Ni', 'Monty': 'Python', 'SPAM': 'SPAAAM'}

Or we could just do that:

l = [('Knights', 'Ni'), ('Monty', 'Python'), ('SPAM', 'SPAAAM')]
d = dict(l) # {'Knights': 'Ni', 'Monty': 'Python', 'SPAM': 'SPAAAM'}

Isn’t is neater?

enumerate(iterable [,start=0])

Ah, I really like this one. If you come from C, you probably write this kind of thing all the time:

for i in range(len(list)):
    # do stuff with list[i], for example, print it
    print i, list[i]

Well. Just don’t. It’s kind of unreadable. What you can do, is use enumerate():

for i, item in enumerate(list):
    # so stuff with item, for example print it
    print i, item

You can also specify the starting point, using the start argument.

isinstance(object, classinfo)

Return true if the object argument is an instance of the classinfo argument, or of a (direct or indirect) subclass thereof.

When you want to test the type of an object, the first thing that comes to mind is using the type() function.

if type(obj) == type(dict):
    # do stuff
elif type(obj) == type(list):
    # do other stuff
...

Instead of doing that, you should use the nice isinstance function, because type was not primarily designed to test the type of an object:

if isinstance(obj, dict):
   # do stuff
elif isinstance(obj, list):
   # do other stuff
...

pow(x, y [,z])

Return x to the power y; if z is present, return x to the power y, modulo z.

If you want to compute x to the power of y, modulo z, you could use

mod = (x ** y) % z

Well yes. But if x=1234567, y=4567676 and z=56, my laptop computes this calculation in 64s.

Instead of using the ** and % operators, use the pow(x, y, z) function: pow(1234567, 4567676, 56). On my laptop, it only takes 0.034s. It’s basically ~2000 times faster. Just food for thoughts.

zip([iterable, ])

This function returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables.

l1 = ('You gotta', 'the')
l2 = ('love', 'built-in')
out = []
if len(l1) == len(l2):
    for i in range(len(l1)):
        out.append((l1[i], l2[i]))
# out = [('You gotta', 'love'), ('the', 'built-in)]

The equivalent “pythonic” code would simply be

l1 = ['You gotta', 'the']
l2 = ['love', 'built-in']
out = zip(l1, l2) # [('You gotta', 'love'), ('the', 'built-in)]

Note that you can do the reverse operation using the * operator:

print zip(*out)
# [('You gotta', 'the'), ('love', 'built-in')]

Conclusion

Python built-in functions are very convenient, they are fast and optimized (they’re written in C), so they might be more efficient that anything you write with Python. Use them extensively :)

I really think that every Python coder should have read the built-in documentation.

Oh and there’s also a nice set of tools in the itertools module. Once again, they’re fast, optimized and awesome.

Comments