Python by Examples

There are lots of languages out there. What makes one better than another? Well, it depends. These are the questions that I use:

Note that answers to these questions vary from person to person and from project to project. Some of them are easy to answer, but others take months to figure out. For example, I initially liked PHP because of its simplicity and thorough documentation, but eventually I learned that I really dislike it.

Generally speaking, Python is the language I most enjoy. I still use a variety of other languages, including C, C++, Java, Perl, and even PHP. Python isn't always the best tool for the job, but it seems to resonate with me more than anything else I've used. Best of all, the more I use it the more I like it.

Give it a try, and see if you like it. You may find some characteristics of it annoying, but try to understand that there's usually a good reason. At first I hated having indentation levels be syntactical, but now I love it. In this tutorial, I will attempt to show why Python makes me smile. Just give it a chance. If you make it through and are sure that it just isn't your thing, make sure to try Ruby, which is very cool but just not my thing.

Using the Tutorial

I am assuming that you have some background in programming, but not necessarily in a language with much resemblance to Python. I will go one step at a time to make sure that everything's clear. It's even possible that a non-programmer will follow most of what's going on, although they are less likely to be wowed anywhere.

If you type python at a command prompt, you'll enter the Python interactive interpreter. It will give you a prompt: ">>> ". Type ^D (control D) to quit at any time. You can type in any of the examples from this page, and the results will be printed right there in real time. Feel free to experiment.

To save you the trouble, I will include output whenever it is printed to the screen. I will include the output as a comment after the code segment that prints it. Note that in Python, a comment line starts with a "#" (hash, pound, etc.).

Primitives and Functions

Assignment in Python is straightforward, with the normal variety of numerical types (including imaginary numbers, which end with a "j"):

a = 3
b = 4.1
c = 2j

Printing out is easy:

print a, b, c
# 3 4.1 2j

Strings can be delimited with single or double quotes. If you don't want escape sequences to be interpreted, make sure to specify it as a "raw" string. Examples:

s = "A string in double quotes."
t = 'A string with\na newline.'
u = r'A raw \n string.'
print s
# A string in double quotes.
print t
# A string with
# a newline.
print u
# A raw \n string.

Python has a built-in printf operator that takes a format string and a list of values:

v = 'str s: %s, float a: %.2f, integer b: %d' % (s, a, b)
print v
# str s: A string in double quotes., float a: 3.00, integer b: 4

Indentation level is syntactical ("get lost, you awkward braces"):

if a > b:
    print a - b
else:
    print b - a
# 1.1

Function definitions and function calls are simple:

def square(x):
    return x**2
print square(a), square(b), square(c)
# 9 16.81 (-4+0j)

It is conventional to make the first line of a function be a string that explains the purpose and usage of the function. This is called a docstring:

def fahr_to_cels(degrees):
    'Convert a temperature from Fahrenheit to Celsius.'
    return (degrees-32) * (5.0/9)
print fahr_to_cels(451)
# 232.777777778

Once a function has a docstring, you can ask for help about it. Note that the response opens up in the less pager.

help(fahr_to_cels)
# Help on function fahr_to_cels in module __main__:
#
# fahr_to_cels(degrees)
#     Convert a temperature from Fahrenheit to Celsius.

Tuples, Lists, Dictionaries, and Iteration

Code that looks "pythonic" usually makes extensive use of tuples, lists, and dictionaries, the most important aggregate data types in Python.

A tuple is a comma-separated sequence of values, usually enclosed in parentheses. Array indexing works as expected:

tup = (1, 2, 3)
print tup[0]
# 1
print tup[2]
# 3
print len(tup)
# 3

Tuples are immutable (unchangable). You can't add, remove, or replace elements in a tuple. As long as you don't need to modify the sequence, tuples are a great choice because they're fast and efficient.

tup[1] = 5
# Traceback (most recent call last):
#   File "", line 1, in ?
# TypeError: object does not support item assignment

Lists are like tuples, except items can be added, removed, and replaced:

lst = [1, 2, 3]
print lst[0]
# 1
lst[1] = 5
lst.append(10)
print lst
# [1, 5, 3, 10]
print len(lst)
# 4

A dictionary is an unordered set of (key, value) pairs. Items are looked up by key.

d = {1: 'a', 'hello': 101, True: 12}
print d['hello']
# 101
d['newitem'] = 'newvalue'
print d['newitem']
# newvalue

Iteration (i.e. for loops) is always done in terms of sequences:

for x in lst:
    print x
# 1
# 5
# 3
# 10

If you want to do a C-style "for (i=0; i<n; i++)", you can create a list with all of the numbers in the range [0, n):

print range(7)
# [0, 1, 2, 3, 4, 5, 6]
print len(range(7))
# 7

You can iterate in a C-ish way by using range. The above for loop over lst can be rewritten non-pythonically as:

for i in range(len(lst)):
    print lst[i]
# 1
# 5
# 3
# 10

Python has list comprehensions, a beautiful way of creating one list from another:

l2 = [x+10 for x in lst]
print l2
# [11, 15, 13, 20]

You can even make a cross-product: a list of pairs (2-tuples) created from two lists. The first item of each pair is from the first list and the second item is from the second list. The resulting list contains all such pairs. Note: it's easier to explain this code in Python than in English!

l1 = ['a', 'b', 'c']
l2 = [1, 2, 3]
crossprod = [(x,y) for x in l1 for y in l2]
print crossprod
# [('a', 1), ('a', 2), ('a', 3), ('b', 1), ('b', 2), ('b', 3), ('c', 1), ('c', 2), ('c', 3)]

A for loop on a dictionary is iteration over the keys in the dictionary.

for key in d:
    print 'Key: %s, Value: %s' % (key, d[key])
# Key: newitem, Value: newvalue
# Key: 1, Value: 12
# Key: hello, Value: 101

Using Objects and Classes

We haven't really showed this yet, but everything in Python is an object. Look at some of the attributes of a string:

s = 'this is a test'
print s.upper()
# THIS IS A TEST
print s.split(' ')
# ['this', 'is', 'a', 'test']
print s.replace('test', 'string')
# this is a string

Of course, you don't need to assign the string to a variable first:

print 'hello'.upper()
# HELLO

In Python, standard operators are implemented by methods that start and end with two underscores:

print 'first' + 'second'
# firstsecond
print 'first'.__add__('second')
# firstsecond
print abs(-13)
# 13
print (-13).__abs__()
# 13
print len('hello')
# 5
print 'hello'.__len__()
# 5
print 100.5 - 50.1
# 50.4
print (100.5).__sub__(50.1)
# 50.4

New instances of a class are created by calling that class. The constructors are often very smart.

print int()
# 0
print int(123.456)
# 123
print float('27.1') + float('0.5')
# 27.6

A class is an object like anything else, and an identifier like int or float is a variable name just like anything else. Assignments involving these objects and variables follow the normal rules.

my_favorite_class = int
print my_favorite_class(17.234)
# 17
int = '34'
print int + 'abc'
# 34abc
print my_favorite_class(int) + 12
# 46

Let's go back to our fahr_to_cels() function from earlier.

def fahr_to_cels(degrees):
    'Convert a temperature from Fahrenheit to Celsius.'
    return (degrees-32) * (5.0/9)

One of the attributes of a function is its docstring, which was discussed earlier. The docstring is just like any other string:

print fahr_to_cels.__doc__
# Convert a temperature from Fahrenheit to Celsius.
newstring = '123' + fahr_to_cels.__doc__ + '123'
print newstring
# 123Convert a temperature from Fahrenheit to Celsius.123

Since a function is just an object, we can assign it to a variable:

func = fahr_to_cels
func(212)
# 100.0

So now the variable fahr_to_cels and the variable func both refer to the same function object. Note that the function object remembers the name it was originally given. You can ask the object for its original name and for other information, like the docstring:

print func.__name__
# fahr_to_cels
print func.__doc__
# Convert a temperature from Fahrenheit to Celsius.

In the above example we retrieved attributes by using the dot operator and typing the name of the attribute. We can also retrieve an attribute whose name is stored in a variable:

attrname = '__doc__'
print fahr_to_cels.__getattribute__(attrname)
# Convert a temperature from Fahrenheit to Celsius.

You can even assign the bound method to a variable:

plus3 = (3).__add__
print plus3(17)
# 20

Creating New Classes

Creating and instantiating classes is easy. Note that the first argument to a method is its object; this removes any conceptual distinction between functions and methods.

class Person(object):
    'An object to keep track of a person and their weight.'

    def __init__(self, name, weight):
        'Construct a new Person object.'
        self.name = name
        self.weight = weight

    def pigout(self):
        'Eat Thanksgiving Dinner.'
        self.weight += 5

    def __str__(self):
        'Convert Person to a string.'
        return self.name + ' (' + str(self.weight) + ' lbs.)'

Create a new person (and implicitly call the constructor, __init__()):

p = Person('Joe', 172.2)
print p.name
# Joe
print p.weight
# 172.2

Convert p to a string (by calling __str__()) and print it out:

print p
# Joe (172.2 lbs.)

Call the pigout() method on Joe, which will add five pounds to his weight:

p.pigout()
print p
# Joe (177.2 lbs.)

Call the pigout() method. This is exactly equivalent to the above.

Person.pigout(p)
print p
# Joe (182.2 lbs.)