Python 3

Table of Contents



Looping Backwards

Use reversed:

colors = ['red', 'green', 'blue']
for color in reversed(colors):

Looping Over Collection and Indices

Use enumerate:

colors = ['red', 'green', 'blue']
for i, color in enumerate(colors):
    print("{} -> {}".format(i, color))

Looping Over Two Collections

names = ['raymond', 'rachel', 'matthew']
colors = ['red', 'green', 'blue', 'yellow']
for name, color in zip(names,colors):
    print("{} -> {}".format(name, color))

Note that the lengths are different.

Looping in Sorted Order

Use sorted:

colors = ['red', 'green', 'blue']
for color in sorted(colors):

To sort by length:

colors = ['red', 'green', 'blue']
for color in sorted(colors, key=len):

Breaking Out of Two Loops and Nested Loops

Python's break only breaks out of one loop. To break out from two, make it a single loop. So:

for x in range(width):
    for y in range(height):
        <do something>

Create a range:

def range_2d(width, height):
    for x in range(width):
        for y in range(height):
            yield x, y

Then, you can do:

for x, y in range_2d(width, height):
    <do something>

More Nested Loops

Instead of:

for i in v:
    for j in w:
        <do something>

you can do

it = ( (i,j) for i in v for j in w ) # creates a GENERATOR
for i,j in it:
    <do something>


Looping Over Dictionary Keys

d = {'matthew': 'blue', 'rachel': 'green', 'raymond': 'red'}
for k in d:
    print k

If you want to change the dictionary while you loop, loop over d.keys():

for k in d.keys():
    if k.startswith('r'):
        del d[k]

Looping Over Dictionary Values

for v in d.values()
   <do stuff>

Looping Over Dictionary Items

for key, value in d.items()
    print("{} --> {}".format(key, value))

Construct Dictionaries from Pairs

d = dict(zip(names, colors))

Counting Occurrences

Use d.get. d.get(item,0) gives d[item] if possible and 0 otherwise.

d = {}
v = [0,0,0,1,1,1,1,1,1,2,2,0,2,1]
for x in v:
    d[x] = d.get(x,0) + 1

There is also d.setdefault(key, default_value), which also creates the d[key] if it does not exist already.

One can also use defaultdict(type), which creates an “empty” dictionary with values of type.

For instance, to create a dictionary grouping stings of names by length:

from collections import defaultdict
d = defaultdict(list)
for name in names:
    key = len(name)

If key does not exist, it creates it and sets the default value for list, which is an empty list. (And for int it is 0.)

Another Construction Example

v = [ 'a', 'b', 'c', 'd' ]
w = [ 1, 2, 3, 4 ]
my_dict = { letter : number for letter, number in zip(v,w) if number != 2 }

gives my_dict as { 'a' : 1, 'c' : 3, 'd' : 4 }.

Function Arguments

Optional Arguments

Use * for optional arguments with no default value.

def my_fct(x, *v):
    print('First value is {}'.format(x))
    if v: # runs if v is not empty
        print('The other values are:')
        for value in v:

You can call it with my_fct(3), my_fct(3,4), my_fct(3,4,5), etc.

Also, if v = [1, 2], then my_fct(3,*v) is the same as my_fct(3,1,2).

Required Keyword Arguments

In Python 3, if

def f(x, y, *, z=0, w=1):
    return x+y+z+w

you cannot call it as f(1,2,3,4), you must call it with f(1,2,x=3,w=4), i.e., the keyword arguments must be entered as keywords.

Misc Tricks

Lambda Functions

Instead of

def f(x,y):
    return x + y


f = lambda x, y: x + y

Map and Filter

If v is a list and f is a function, then

fv = map(f,v)

applies f to entries of v. In Python 3 it is iterable. (To make a list, do fv = list(map(v)).)

Now if test is a conditional function,

testv = filter(test,v)

gives only the elements of v satisfying test. Similar to

testv = [ x in v if test(x) ]

but in Python 3 it gives an iterable, not a list.

Avoid True/False Flags

You can use the else part of a for loop. So, instead of

def find(seq, target):
    found = False
    for i, value in enumerate(seq):
        if value == target:
            found = True
    if not found:
        return -1
    return i


def find(seq, target):
    for i, value in enumerate(seq):
        if value == target:
            found = True
        return -1
    return i

The else is like a nobreak: if the look finished normally, it skips the else part. If there is a break in the look, it runs the else part.


To save functions from recomputing the same value (with the expense of saving the computed values in memory) is to use@cache. So, instead of:

def my_fct(x, saved={}):
    if x in saved:
        return saved[x]
     <compute result>
     saved[x] = result
     return result


def my_fact(x):
    <compute result>
    return result

Open/Close Files

Instead of:

f = open('data.txt')
    data =


with open('data.txt') as f:
    data =

Generator Expressions

Instead of

sum([i**2 for i in range(10)])


sum(i**2 for i in range(10))

Named Tuples

from collections import namedtuple
Color = namedtuple('Color',['hue', 'saturation', 'luminosity'])
p = Color(170, 0.1, 0.6)
if p.saturation > 0.5:
if p.luminosity > 0.5:

See also:


If you want to loop over the squares of integers from 1 to 1000, instead of creating the list

[ i**2 for i in range(1,1001)]

and looping, create the generator/iterator:

( i**2 for i in range(1,1001))

It's better in most cases to return generators/iterators instead of lists. So instead of:

def cubes(n):
    res = []
    for i in range(n):
    return res

you can do

def cubes(n):
    for i in range(n):
         yield i**3

We can make it a list if we want to with list(cubes(10)), but we can use to iterate (only once per call), like:

for i in cubes(10):
    <do something with i>

Or, to extract the first three elements:

c = cubes(100000)

Conditional Assignment

x = 1 if <condition> else 0

Adding Commas to Printed Numbers

number = 100000000
print('The number is {:,}'.format(number))


a, b, c = (1, 2, 3, 4, 5)

gives an error. In Python 3 we can do

a, b, *c = (1, 2, 3, 4, 5)

gives an a = 1, b = 2, c = [3, 4, 5].

a, b, *_ = (1, 2, 3, 4, 5)

gives an a = 1 and b = 2.

a, b, *c, d  = (1, 2, 3, 4, 5)

gives an a = 1, b = 2, c = [3, 4], and d = 5.

Values Treated as False

The following values are treated as False: “” (empty string), 0, 0.0, [] (empty list), () (empty tuple), {} (empty dictionary), False, None. If variable then is any of those, then

if variable:

will not print OK, but will otherwise.

Creating Empty Set

You cannot create and empty set wit my_set = {} as it creates an empty dictionary. So, you do it with my_set = set().

This also works for lists, tuples or dictionaries:

empty_list = []
empty_list = list()
empty_tuple = ()
empty_tuple = tuple()
empty_dict = {}
empty_dict = dict()