Introduction to Python

Overview

Python

Links

Getting Started

Like several other languages including ML and Ruby, you use Python in two ways:

Writing simple scripts

Call this file hello.py

print 'Hello, world'

and run it like this

$ python hello.py Hello, world

Note that Python has a print statement (not a print function), that automatically puts a newline at the end! Cool, huh? Another simple script:

"""This script prints some Pythagorean triples."""

for c in range(1, 100):
    for b in range(1, c):
        for a in range(1, b):
            if a * a + b * b == c * c:
                print '(', a, b, c, ')'

And another

"""This script writes the Fibonacci numbers up to and including
the first commandline argument.
"""

import sys

n = int(sys.argv[1])

a, b = 0, 1
while b <= n:
    print b,
    a, b = b, a+b
$ fib.py 300 1 1 2 3 5 8 13 21 34 55 89 144 233 $ python fib.py blah blah Traceback (most recent call last): File "fib.py", line 10, in ? n = int(sys.argv[1]) ValueError: invalid literal for int(): blah

Using interactive mode

The prompt is ">>>". The continuation line is "...". For multiline inputs, finish with a blank line (hit Enter without entering anything first)

$ python
Python 2.4.4c1 (#2, Oct 11 2006, 21:51:02)
[GCC 4.1.2 20060928 (prerelease) (Ubuntu 4.1.1-13ubuntu5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 5 * 3 + 6 / 1
21
>>> 5 / 2
2
>>> 5.0 / 2
2.5
>>> 'dog'
'dog'
>>> x = 4
>>> x
4
>>> {'x': 4, 'y': 6}
{'y': 6, 'x': 4}
>>> s = 'hello there'
>>> s.upper()
'HELLO THERE'
>>> s.split(' ')
['hello', 'there']
>>> 5 < 9
True
>>> x = [1, True, 7.5, 'Hello', {'name':'sparky', 'breed':'shepherd'}, []]
>>> x[2]
7.5
>>> x[4]
{'breed': 'shepherd', 'name': 'sparky'}
>>> x[4]['name']
'sparky'
>>> x,y,z = 10,20,30
>>> x,y = y,x
>>> if x == 20:
...     print 'dog'
...
dog
>>> def triple(x):
...     return x * 3
...
>>> triple(5)
15
>>> x + y + 2j
(30+2j)
>>> (5-1j)*1j
(1+5j)
>>> triple(1j)
3j

Good to Know

Learning By Examples

Objects and Types

Absolutely everything in Python is an object. You get the id of an object with the id function, and the type of the object with the type function.

>>> id(8)
9786484
>>> id(202342353245553)
10527880
>>> id(False)
504954072
>>> id(2 < -4)
504954072
>>> id(None)
505028096
>>> id("hello")
10951328
>>> id(id)
10532224

>>> type(8)
<type 'int'>
>>> type(242354234235665657543)
<type 'long'>
>>> type(None)
<type 'NoneType'>
>>> type("woo")
<type 'str'>
>>> type(u"woohoo")
<type 'unicode'>
>>> type(False)
<type 'bool'>
>>> type(lambda x: x * x)
<type 'function'>
>>> type(id)
<type 'builtin_function_or_method'>
>>> type({'CA':'Sacramento','HI':'Honolulu','AK':'Juneau'})
<type 'dict'>
>>> type(type)
<type 'type'>
>>> type(type(3))
<type 'type'>
>>> int
<type 'int'>
>>> type(2.77e6)
<type 'float'>
>>> type(3-3j)
<type 'complex'>

A type's constructor has the same name as the type. Most constructors do the obvious thing when given arguments of different types.

>>> str(42)
'42'
>>> bool(35443)
True
>>> bool(0)
False
>>> int(False)
0
>>> int(True)
1
>>> float(92)
92.0
>>> int(89.3221)
89
>>> int(99.99999999)
99
>>> int(-99.9999)
-99
>>> float(False)
0.0
>>> complex(5)
(5+0j)
>>> complex(3.6, 99)
(3.6000000000000001+99j)
>>> long(32.4E39)
32399999999999999195056519073840702160896L
>>> unicode(25)
u'25'
>>> str(8.9E5)
'890000.0'
>>> int("32")
32
>>> list((3,7,5))
[3, 7, 5]
>>> tuple([1,2,-17,"dog"])
(1, 2, -17, 'dog')
>>> list("abc")
['a', 'b', 'c']
>>> list({"x": 5, "y": 7})
['y', 'x']
Exercise: Try the int constructor on a string holding a number you know is well beyond the range of integers on your machine.
Exercise: What does int("cafe") return? What about int("cafe", 16)? Why?

Container Types

The three kinds of built-in containers are sequences, sets, and dictionaries

The built-in container types are

For all sequences s and t, sequence elements x, and integers i, j, k, and n, you can write

    s[i]       s[i:j]     s[i:j:k]    s[:i]      s[i:]
    len(s)
    x in s
    s + t      s * n
    s < t      s <= t
    s == t     s != t     s >= t      s > t
    iter(x)

Functions

Functions are introduced with def, and called with the usual f(x) notation.

"""This is a simple script that displays the mean and median
of an array of values, passed in on the command line.
"""

import sys;
import operator;

def median(a):
    """Return the median of sequence a."""
    a = sorted(a)
    length = len(a)
    if length % 2 == 1:
        return a[length/2]
    else:
        return (a[length/2] + a[length/2 - 1]) / 2.0

def sum(a):
    """Return the sum of the values in the sequence a.  Python
    already has a built-in sum function so you'd never actually
    write one yourself, but this is one way to do it if you
    wanted to.
    """
    return reduce(operator.add, a, 0)

def mean(a):
    """Return the mean of the values in sequence a."""
    return float(sum(a)) / len(a)

print "input array is", sys.argv
numbers = [int(x) for x in sys.argv[1:]];
print "list is:", numbers
print "sum is:", sum(numbers)
print "mean is:", mean(numbers)
print "median is:", median(numbers)
print "list is:", numbers, "(just making sure it was not changed)"

You can also have defaults for arguments, and call them with the parameter names:

>>> def f(x, y=5, z=10):
...     return (x, y, z)
...
>>> f(1)
(1, 5, 10)
>>> f(1,7)
(1, 7, 10)
>>> f(1,8,20)
(1, 8, 20)
>>> f(2,3,5,7)
Traceback (most recent call last):
  File "", line 1, in ?
TypeError: f() takes at most 3 arguments (4 given)
>>> f(2,z=5)
(2, 5, 5)
>>> f(x=4,y=9)
(4, 9, 10)
>>> f(z=1,x=10,y=3)
(10, 3, 1)

You can have calls with an unlimited number of arguments

>>> def g(x, *y):
...     return "x is " + str(x) + " and y is " + str(y)
...
>>> g(4)
'x is 4 and y is ()'
>>> g(3, 4)
'x is 3 and y is (4,)'
>>> g(8,3,4,5,6,2,3)
'x is 8 and y is (3, 4, 5, 6, 2, 3)'

Higher-order Functions

"""Examples of higher order functions in Python.

This script contains both examples of defining your
own higher order functions, and how you use the builtins
map, reduce, and filter.
"""

def compose(f, g):
    """Returns the functional composition of f and g"""
    return lambda x: f(g(x))

def twice(f):
    """Returns the function which applies f to its argument twice"""
    return compose(f, f);

# Some plain old functions

def isOdd(x): return x % 2 == 1
def twoXPlusY(x, y): return 2 * x + y
def square(x): return x * x
def addSix(x): return x + 6

# The value of a variable can be a function

addSixThenSquare = compose(square, addSix)
addTwelve = twice(addSix)

# Illustration of the functions via unit tests

failures = 0
def assertEquals(x, y):
    global failures
    if x != y: failures += 1

assertEquals(addSixThenSquare(9), 225)
assertEquals(twice(square)(3), 81)
assertEquals(addTwelve(100), 112)

# map, filter, and reduce are builtins.

assertEquals(map(square, range(5)), [0, 1, 4, 9, 16])
assertEquals(filter(isOdd, range(7)), [1, 3, 5])
assertEquals(reduce(twoXPlusY, [3, 6, -4, 2, -7], 0), 77)

print failures, "failure(s)"

Also, The Linux Gazette has an article on Functional Programming in Python.

For more on closures in Python, see this explanation by Jacek Generowicz.

List Comprehensions

A list comprehension just a list written with an expression used to generate the list elements. They are often used in place of some functional programming constructs

>>> a = [1, 2, 10, 6]
>>> b = [3, 0, 4, -8]
>>> [4 * x for x in a]
[4, 8, 40, 24]
>>> [2 / x + 5 for x in a if x < 4]
[7, 6]
>>> [x + y for x in a for y in b]
[4, 1, 5, -7, 5, 2, 6, -6, 13, 10, 14, 2, 9, 6, 10, -2]
>>> [(x, x**3) for x in a]
[(1, 1), (2, 8), (10, 1000), (6, 216)]
>>> [x + y for x in a for y in b if y <= 0]
[1, -7, 2, -6, 10, 2, 6, -2]
>>> [a[i] * b[i] for i in range(len(a))]
[3, 0, 40, -48]
>>> [str(round(355/113.0, i)) for i in range(1,6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']
>>> [(i, 2**i) for i in range(10)]
[(0, 1), (1, 2), (2, 4), (3, 8), (4, 16), (5, 32), (6, 64), (7, 128), (8, 256), (9, 512)]
>>> [x for x in [y*y for y in range(10)] if x % 2 == 0]
[0, 4, 16, 36, 64]
>>> names = ["ALICE", "BOb", "cAROl", "daVE"]
>>> [(n.lower(), n.upper()) for n in names]
[('alice', 'ALICE'), ('bob', 'BOB'), ('carol', 'CAROL'), ('dave', 'DAVE')]
>>> [i for i in range(10,30) if i not in range(5, 40, 2)]
[10, 12, 14, 16, 18, 20, 22, 24, 26, 28]
>>> [(a,b,c) for c in range(1,30) for b in range(1,c) for a in range(1,b) if a*a+b*b==c*c]
[(3, 4, 5), (6, 8, 10), (5, 12, 13), (9, 12, 15), (8, 15, 17),
(12, 16, 20), (15, 20, 25), (7, 24, 25), (10, 24, 26), (20, 21, 29)]

Python list comprehensions are

Operators

Operators are really methods of a class that get a nice syntax via rewriting rules.

>>> x = 3;
>>> x.__add__(4)
7

Modules

Modules are trivial in Python: no special syntax is required: the module name is just the file name. For example, put this code in roman.py

"""A module containing a single subroutine that returns the roman
numeral representation of an integer."""

def to_roman(n):
    """Returns a string representing the roman numeral for n"""

    if (type(n) != int):
        raise Exception(repr(n) + " is not an integer");
    if (n <= 0):
        raise Exception("%d has no Roman equivalent" % n);

    map = [
        (1000, 'M'),
        (900, 'CM'),
        (500, 'D'),
        (400, 'CD'),
        (100, 'C'),
        (90, 'XC'),
        (50, 'L'),
        (40, 'XL'),
        (10, 'X'),
        (9, 'IX'),
        (5, 'V'),
        (4, 'IV'),
        (1, 'I'),
    ]

    roman_string = ""
    for value, name in map:
        while (value <= n):
            roman_string += name
            n -= value
    return roman_string

if __name__ == "__main__":
    n = input('Enter an integer: ')
    print n, "is", to_roman(n)
    print "And here are other interesting roman numerals"
    for n in [3, 89, 22, 11]:
        print n, "is", to_roman(n)

Here is a unit tester that uses it

"""A trivial unit test for the roman package."""

import roman

test_cases = {
   3: 'III',
   89: 'LXXXIX',
   1002: 'MII',
   11: 'XI',
   444: 'CDXLIV',
}

# Tests roman.to_roman
for n in test_cases:
    expected = test_cases[n];
    actual = roman.to_roman(n);
    if expected != actual:
        raise Exception("Found %s but expected %s for %s " %
                        (actual, expected, n))

# If we didn't die, we made it.
print "All tests passed"

Exceptions

Here is an illustration of the try statement

"""A simple script that reads from integers from standard
input and writes their roman equivalents to standard output.
The input file is assumed to have one integer per line.
Blank lines are allowed and will be skipped.
"""

import roman, sys, string

for line in sys.stdin.readlines():
    line = string.strip(line);
    if line:
        try:
            print line, "is", roman.to_roman(int(line))
        except Exception, e:
            print e

Classes

import math

class Circle:
    "A circle with a 2-D center point and a radius."

    def __init__(self, x, y, radius):
        self.x = x
        self.y = y
        self.radius = radius

    def area(self):
        "Returns the area of the circle"
        return math.pi * (self.radius ** 2)

    def perimeter(self):
        "Returns the circumference of the circle"
        return math.pi * self.radius * 2

    def expand(self, factor):
        "Increases the radius by the given factor"
        self.radius *= factor
        return self

    def move(self, dx, dy):
        "Moves the center point by <dx, dy>"
        self.x += dx
        self.y += dy
        return self

    def __str__(self):
        return "Circle at (%g,%g) with r=%g" % (self.x, self.y, self.radius)

Using

>>> from circle import *
>>> c = Circle(4, 3, 10)
>>> c.area()
314.15926535897933
>>> c.perimeter()
62.831853071795862
>>> c.move(3, 2)
<circle.Circle instance at 0x00A77058>
>>> print c
Circle at (7,5) with r=10
>>> c.move(-3,2).expand(5)
<circle.Circle instance at 0x00A77058>
>>> print c
Circle at (4,7) with r=50
>>> Circle.area.__doc__
'Returns the area of the circle'
Exercise: Try "help(Circle)"

Inheritance and Polymorphism

Nothing too unusual here, except that there's no built-in super keyword, so __init__ calls to a superclass must name the superclass

"""A module with talking animals."""

class Animal:
    def __init__(self, name):
        self.name = name

    def speak(self):
        print self.name, "says", self.sound()

class Cow(Animal):
    def __init__(self, name):
        Animal.__init__(self, name)

    def sound(self):
        return "moo"

class Horse(Animal):
    def __init__(self, name):
        Animal.__init__(self, name)

    def sound(self):
        return "neigh"

class Sheep(Animal):
    def __init__(self, name):
        Animal.__init__(self, name)

    def sound(self):
        return "baaaaa"

if __name__ == "__main__":
    s = Horse("CJ")
    s.speak()
    c = Cow("Bessie")
    c.speak()
    Sheep("Little Lamb").speak()

Iterators

An iterator is like an "on-demand sequence" — it saves space and can potentially be infinite. Compare

for line in file.readLines():
    # ...

with

for line in file:
    # ...

An iterator is any object with two methods:

Any object that has an __iter__() method that returns an iterator can be used in a for statement.

"""A couple of interesting iterators."""

class fibs:
    """Fibonacci iterator (infinite): 0, 1, 1, 2, 3, 5, 8, ..."""

    def __init__(self):
        self.a, self.b = 0, 1

    def next(self):
        current, self.a, self.b = self.a, self.b, self.a + self.b
        return current

    def __iter__(self):
        return self

class collatz:
    """Collatz sequence iterator, supply start value at initialization"""

    def __init__(self, start):
        self.n = start
        self.started = False

    def next(self):
        if not self.started:
            self.started = True
            return self.n
        elif self.n == 1:
            raise StopIteration
        elif self.n % 2 == 0:
            self.n = self.n / 2
        else:
            self.n = 3 * self.n + 1
        return self.n

    def __iter__(self):
        return self

if __name__ == "__main__":

    # Demonstrate fibonacci iterator
    f = fibs()
    for i in f:
        print i,
        if i > 1000000:
            break;
    print
    print

    # Demonstrate collatz iterator
    c = collatz(47)
    for i in c:
        print i,
    print
    print

Generators

Generators are a way cool way to make iterators — they sort of generate the iterator for you.

"""A couple of interesting generators."""

def fib():
    "Fibonacci generator (infinite): 0, 1, 1, 2, 3, 5, 8, ..."
    a, b = 0, 1
    while True:
        current, a, b = a, b, a + b
        yield current

def collatz(n):
    "Collatz generator starting at n"
    while True:
        yield n
        if n == 1:
            return
        elif n % 2 == 0:
            n = n / 2
        else:
            n = 3 * n + 1

if __name__ == "__main__":

    # Show off the fibonacci generator
    for i in fib():
        print i,
        if i > 1000000:
            break;
    print
    print

    # Show off the collatz generator
    for i in collatz(47):
        print i,
    print
    print

Reference Material

Keywords

    and       del       from      not       while
    as        elif      global    or        with
    assert    else      if        pass      yield
    break     except    import    print
    class     exec      in        raise
    continue  finally   is        return
    def       for       lambda    try

Grammar

Types

From the Python Reference Manual, Section 3.2:

TypeNotes
NoneType contains only one value: None
NotImplementedType contains only one value: NotImplemented
EllipsisType (ellipsis) contains only one value: Ellipsis
Number all numbers are immutable
Integer
IntType (int) at least -2147483648..2147483647
LongType (long) range limited only by available memory
BooleanType (bool) contains only two values: True, False
FloatType (float) hardware's double-precision type
ComplexType (complex) pair of hardware doubles (z.real, z.imag)
Sequence finite, ordered, indexed from 0, len(), a[i], a[i:j]
Immutable Sequence a sequence that cannot have its value changed
StringType (str) contain bytes (convert to/from ints with chr() and ord())
UnicodeType (unicode) contain code units (convert to/from ints with unichr() and ord())
TupleType (tuple) written as (), (x,), (x,y), (x,y,z), etc.
Mutable Sequence subscripted and slice forms can be lvalues; del statement okay
ListType (list) written as [], [x], [x,y], [x,y,z], etc.
Mapping something indexable with the a[k] syntax, k can be almost anything, not just an integer
DictionaryType (dict) the only kind of mapping type
Callable anything supporting the call syntax
User-defined Function created by a function definition
User-defined Method basically a function defined within a class
Generator Function any function with a yield statement
Built-in Function wrapper around a C function (e.g. len(), math.sin())
Built-in Method wrapper around a C function, w/ implicit __self__ argument
Classic Class "calling" a class is sugar for construction and calling __init__()
Class Type new-style classes, similar to classic classes but can use __new__()
Class Instance any instance of a class with a __call__() method
Module a collection of definitions and statements put into a file and imported into other code
Class created by a class definition
Class Instance an object created by invoking a constructor
File an open file, created with open() and related operations. sys.stdin and sys.stdout are examples.
Internal used internally, but exposed to the programmer
Code bytecode. Immutable.
Frame execution frames, occurring in traceback objects
Traceback created when an exception is thrown, accessible within the tuple returned by sys.exc_info()
Slice examples: a[i:j:step], a[i:j, k:n], a[..., i:j]
Static Method created by built-in staticmethod() constructor
Class Method created by built-in classmethod() constructor

Statements

__builtin__

The symbol table in this module is always searched last, so it's like all these names are made available to all scripts and the interactive shell.

On ActiveState Python 2.4 for Windows, the module contains:

ArithmeticError AssertionError AttributeError DeprecationWarning EOFError Ellipsis EnvironmentError Exception False FloatingPointError FutureWarning IOError ImportError IndentationError IndexError KeyError KeyboardInterrupt LookupError MemoryError NameError None NotImplemented NotImplementedError OSError OverflowError OverflowWarning PendingDeprecationWarning ReferenceError RuntimeError RuntimeWarning StandardError StopIteration SyntaxError SyntaxWarning SystemError SystemExit TabError True TypeError UnboundLocalError UnicodeDecodeError UnicodeEncodeError UnicodeError UnicodeTranslateError UserWarning ValueError Warning WindowsError ZeroDivisionError _ __debug__ __doc__ __import__ __name__ abs apply basestring bool buffer callable chr classmethod cmp coerce compile complex copyright credits delattr dict dir divmod enumerate eval execfile exit file filter float frozenset getattr globals hasattr hash help hex id input int intern isinstance issubclass iter len license list locals long map max min object oct open ord pow property quit range raw_input reduce reload repr reversed round set setattr slice sorted staticmethod str sum super tuple type unichr unicode vars xrange zip

Standard Modules

There are a few hundred "standard" modules in the Python Library.