Containers: Lists

Authors: Tom Dunham
Date: 2009-03-31

Containers

Containers are objects that have a value made up of other objects.

They allow us to bundle a number of pieces of data (often related) together and manipulate them as a unit.

Container Types

A container type contains references to other objects, the references are part of the container's value. What are references? Ask me later.

Lists

Objects of type list have a value that is made up from other values.

>>> li = [2, 3, 5, 7]
>>> li
[2, 3, 5, 7]

Lists (2)

You can get at these contained values by index

>>> li
[2, 3, 5, 7]
>>> li[0]
2
>>> li[3]
7

Lists (3)

You can put any type of values into a list

>>> li = ["any",  "type",  "of", "values"]
>>> li[0]
'any'

And you can mix types in the same list

>>> li = [1, "toothpick", 2.0, "vegan"]
>>> li
[1, 'toothpick', 2.0, 'vegan']

Lists (4)

The built-in function len returns the number of items in a list

>>> li
[1, 'toothpick', 2.0, 'vegan']
>>> len(li)
4

Exercise

See handout

Do these without using the computer, then check your answers

  1. What does this program print?

    li = [2, 3, 5, 7, 11, 13, 17, 19]
    i = 1
    while i < 3:
        print li[i], "-"
        i = i + 1
    print li[3]
    
  2. What does this program print?

    li = [2, 3, 5, 7, 11, 13, 17, 19]
    for i in li:
        if i > len(li):
            print i
    

Lists

Lists have a different property to the objects we have seen so far - you can change their value.

>>> li = [2, 3, 5, 7]
>>> li
[2, 3, 5, 7]
>>> li[1] = 11
>>> li
[2, 11, 5, 7]

Objects which have a changeable value are called mutable objects.

Storage

http://farm1.static.flickr.com/1/729822_25ba163c9a_m.jpg

When you create an object it is stored on the heap.

As well as a type and a value, objects have an identity. An object's identity never changes.

Python uses identities to refer to objects - it uses an object's identity to find it on the heap.

When you evaluate a name, Python uses the identity to find the object that the name is bound to.

Identity

Two names can be bound to the same object, this is an alias.

>>> foo = 1
>>> bar = 1
>>> id(foo)
13130360
>>> id(bar)
13130360
>>> id(foo) == id(bar)
True

Alias

If the object is mutable, it can be changed via either name

>>> a = [42]
>>> b = a
>>> b
[42]
>>> id(a)
48149048
>>> id(b)
48149048
>>> id(a) == id(b)
True

Alias (2)

>>> b[0] = 84
>>> b
[84]
>>> a
[84]

Side Effects

When you call a function, its parameters become aliases

>>> def crazyfy(lst):
...     lst[1] = "crazy"
...
>>> li = ["hello", "happy", "world"]
>>> crazyfy(li)
>>> li
['hello', 'crazy', 'world']

Changes to objects passed into a function are called side-effects.

Exercise

See handout

  1. After executing these
>>> foo = 1
>>> bar = foo

What is the value of this expression? id(foo) == id(bar)

  1. What does this program print?

    def func(plist):
        nlist = [1,2,3]
        print id(nlist)
        print id(plist)
    
    mylist = [1,2,3]
    func(mylist)
    
  1. What does this program print?

    list1 = [1, 2, 3, 2, 5, 6]
    list2 = [1, 1, 2, 6, 5, 7]
    i = 0
    while i < 5:
        if list1[i] == list2[i]:
            print list1[i], "-",
        i = i + 1
    print len(list1)
    

Append

Add a single item to the end with append

>>> li = ["a", "b", "mpilgrim", "z", "example"]
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li.append("new")
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new']

Insert

Insert an item at a given point with insert

>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new']
>>> li = ['a', 'b', 'mpilgrim', 'z', 'example', 'new']
>>> li.insert(2, "newnew")
>>> li
['a', 'b', 'newnew', 'mpilgrim', 'z', 'example', 'new']

Extend

Add a sequence of items with extend

>>> li
['a', 'b', 'newnew', 'mpilgrim', 'z', 'example', 'new']
>>> li.extend(["two", "elements"])
>>> li
['a', 'b', 'newnew', 'mpilgrim', 'z', 'example', 'new',
'two', 'elements']

Delete

Delete an item with del

>>> del li[2]
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']

Nesting

You can put variables of any type into a list, including other lists

>>> li = [[1,2], [3,4]]

Range

There is a built-in function, range, to create numeric ranges

>>> range(0, 10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Note the first value is inclusive and the second exclusive

>>> range(10, 0, -1)
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

For

A list is a sequence, and can be processed by the for loop

acc = []
for rs in ["GAATTC", "CCWGG", "GGATCC", "AAGCTT"]:
    acc.append(rs.lower())

This could be done by index, using range

acc = []
enz = ["GAATTC", "CCWGG", "GGATCC", "AAGCTT"]
for i in range(0, len(enz)):
    acc.append(rs.lower(enz[i]))

List Slices

A list slice is a copy of the list between two indexes.

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[0:3]
['a', 'b', 'mpilgrim']

Note the first item is inclusive, and the second is exclusive.

>>> li[1:3]
['b', 'mpilgrim']

List Slices

This works backwards too

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[1:-1]
['b', 'mpilgrim', 'z']

Copy a list

>>> li[:]
['a', 'b', 'mpilgrim', 'z', 'example']

Searching a list

>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example',
 'new', 'two', 'elements']
>>> li.index("example")
5
>>> li.index("new")
2
>>> li.index("c")
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
ValueError: list.index(x): x not in list

String->List

>>> example = "Gilbert,Sullivan"
>>> lex = example.split(",")
>>> lex
['Gilbert', 'Sullivan']

List->String

>>> lex
['Gilbert', 'Sullivan']
>>> "|".join(lex)
'Gilbert|Sullivan'
>>> "".join(lex)
'GilbertSullivan'

>>> " and ".join(["Gilbert", "Sullivan", "Tom", "Francis"])
'Gilbert and Sullivan and Tom and Francis'

String->List

>>> example
'Gilbert,Sullivan'
>>> list(example)
['G', 'i', 'l', 'b', 'e', 'r', 't', ',', 'S', 'u', 'l', 'l', 'i', 'v', 'a', 'n']

Exercise

See handout

  1. What is the value of li after the last statement?

    li = [2, 3, 4, 5, 7, 8, 10, 11, 12, 13]
    
    li.insert(4, 6)
    li.extend([14, 15])
    li.remove(4)
    li.append(17)
    
  2. Write a function, revlist which takes a list as a parameter and returns a copy of the list in reverse order. The original list should remain unchanged.

  3. Write a function revstr which takes a string parameter and returns a new string which is the reverse of the original.

  4. Write a function to calculate the reverse-complement of a sequence. That is, translate all A->T, T->A, C->G, G->C and reverse the order.

  5. optional There is more than one way to do question 3. Use dir and help to investigate list and try to find a method to help you.

  6. optional Write functions that calculate the mean, median, mode and standard deviation of a list of values. Investige the built-in functions min and max, and the math.sqrt function.