Source

Lists

Iterating Over a List

Problem

You have a sequence, and you wish to loop over its contents.

Solution

This is the purpose of the for statement:

for item in [1,2,3,4,5]:
      print item

This will work for tuples and strings, too.

Discussion

To iterate over a list in reverse order, the traditional solution before Python 2.4 was to simply reverse the list:

List.reverse()
for item in list:
   # ... do something with item ...

However, this modifies the list itself, so as of Python 2.4, a built-in reverse iterator is also available:

for item in reverse(List):
    # do something with your item

This allows reverse iteration over any sequence without modifying the underlying sequence, and therefore allows easy iteration over immutable sequences such as strings or tuples:

s = "abcd"
s.reverse()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'str' object has no attribute 'reverse'
>>> for i in reversed(s):
...     print i
...
d
c
b
a

An equivalent function, sorted, exists for sorting sequences.

<<<

Note ~~~~ This will probably require a modern Python example of its own.

<<<

Here’s another way to iterate backwards when you have some other sequence type like a tuple or a string, or if reversing the list is unacceptable to you. You’ll have to loop over the indices, from the length of the sequence minus one, down to zero.

for i in range(len(seq)-1, -1, -1):
   item = seq[i]
   # ... do something with item ...

Multidimensional Lists

Problem

You wish to create a list of lists.

Solution

This obvious solution for creating a list of N lists is wrong; see the Discussion for an explanation.

LL = [ [] ] * N

Instead, build an N-element list first, and then replace each element with a list.

LL = [None] * N
for i in range(N): LL[i] = []

If you want to fill out the contained lists with default values, simply replace [] with an expression like N*[0]. Elements could then be retrieved by accessing LL[i][j].

Discussion

Why doesn’t [ [] ] * N work as expected? When multiplying a list, Python copies the contents of the list //by reference//.

This means that you’ll wind up with a list containing N references to the same objects, which is fine for immutable objects such as floating point numbers or tuples, but can be confusing with mutable objects such as lists. To make this clearer, consider the list constructed for N=5.

What happens when you append an element to the first list?

>>> LL = [ [] ] * N
>>> print LL
[[], [], [], [], []]
>>> LL[0].append(1)
>>> LL
[[1], [1], [1], [1], [1]]

All of the lists are modified, not just the first oneThe ~~~ is operator will tell you that all the elements of LL are actually the same list; a true value is returned by LL[0] is LL[1].

A common use of multi-dimensional lists is to store matrices. Before reinventing the wheel and writing yet another matrix type, take a careful look at [[Numeric Python|http://www.python.org/topics/scicomp]], which includes a matrix type, interfaces to libraries of functions such as LINPACK, and lots of other modules useful for numeric work.

Removing Duplicates from a List

Problem

You have a list, and wish to ensure that each item in the list is unique, only occurring once. For example, if your list is [1,4,5,2,4], you would want to remove one of the 4’s.

Solution

If you can reorder the list, sort it to put duplicate values next to each other. If the list is sorted, then removing duplicates requires just a single loop. Note that the opening test for the length of the list is required - without it, if the list is empty, this code will raise an exception.

if len(List) > 1:
   List.sort()         # Sort the list

   # Walk from the end of the list to the beginning;
   # if two elements are identical, delete one of them.
   last = List[-1]     # Start with the last element

   for i in range(len(List)-2, -1, -1):
       if last==List[i]:
           del List[i]
       else:
           last=List[i]

If all the elements of the list can be used as dictionary keys, you can create a dictionary with the list elements as keys, and take the result of the dictionary’s keys() method as the new list.

d = {}
for x in List: d[x] = x
List = d.keys()

Splitting a list into roughly equal parts

There are several ways to to this, but my favorite so far is this one:

def split_seq(seq, num_pieces):
  start = 0
  for i in xrange(num_pieces):
    stop = start + len(seq[i::num_pieces])
    yield seq[start:stop]
    start = stop