Python Programming/Lists
A list in Python is an ordered group of items (or elements). It is a very general structure, and list elements don't have to be of the same type. For instance, you could put numbers, letters, and strings all on the same list.
If you are using a modern version of Python (and you should be), there is a class called 'list'. If you wish, you can make your own subclass of it, and determine list behaviour which is different than the default standard. But first, you should be familiar with the current behaviour of lists.
Contents |
List notation [edit]
There are two different ways to make a list in Python. The first is through assignment ("statically"), the second is using list comprehensions("actively").
To make a static list of items, write them between square brackets. For example:
[ 1,2,3,"This is a list",'c',Donkey("kong") ]
A couple of things to look at.
- There are different data types here. Lists in Python may contain more than one data type.
- Objects can be created 'on the fly' and added to lists. The last item is a new kind of Donkey.
Writing lists this way is very quick (and obvious). However, it does not take into account the current state of anything else. The other way to make a list is to form it using list comprehension. That means you actually describe the process. To do that, the list is broken into two pieces. The first is a picture of what each element will look like, and the second is what you do to get it.
For instance, lets say we have a list of words:
listOfWords = ["this","is","a","list","of","words"]
List comprehensions [edit]
--> see also Tips and Tricks
We will take the first letter of each word and make a list out of it (using so-called list comprehension).
>>> listOfWords = ["this","is","a","list","of","words"] >>> items = [ word[0] for word in listOfWords ] >>> print items ['t', 'i', 'a', 'l', 'o', 'w']
List comprehension allows you to use more than one for statement. It will evaluate the items in all of the objects sequentially and will loop over the shorter objects if one object is longer than the rest.
>>> item = [x+y for x in 'flower' for y in 'pot'] >>> print item ['fp', 'fo', 'ft', 'lp', 'lo', 'lt', 'op', 'oo', 'ot', 'wp', 'wo', 'wt', 'ep', 'eo', 'et', 'rp', 'ro', 'rt']
List comprehension also allows you to use an if statement, to only include members into the list that fulfill a certain condition. We can thus exclude all cases where x is equal to w and y is equal to o; or we can only exclude the case where x is equal to w and y is equal to o (and thus removing the 'wo' from the list).
>>> print [x+y for x in 'flower' for y in 'pot'] ['fp', 'fo', 'ft', 'lp', 'lo', 'lt', 'op', 'oo', 'ot', 'wp', 'wo', 'wt', 'ep', 'eo', 'et', 'rp', 'ro', 'rt'] >>> print [x+y for x in 'flower' for y in 'pot' if x != 'w' and y != 'o' ] ['fp', 'ft', 'lp', 'lt', 'op', 'ot', 'ep', 'et', 'rp', 'rt'] >>> print [x+y for x in 'flower' for y in 'pot' if x != 'w' or y != 'o' ] ['fp', 'fo', 'ft', 'lp', 'lo', 'lt', 'op', 'oo', 'ot', 'wp', 'wt', 'ep', 'eo', 'et', 'rp', 'ro', 'rt']
Python's list comprehension does not define a scope. Any variables that are bound in an evaluation remain bound to whatever they were last bound to when the evaluation was completed:
>>> print x, y r t
This is exactly the same as if the comprehension had been expanded into an explicitly-nested group of one or more 'for' statements and 0 or more 'if' statements.
List creation shortcuts [edit]
Python provides a shortcut to initialize a list to a particular size and with an initial value for each element:
>>> zeros=[0]*5 >>> print zeros [0, 0, 0, 0, 0]
This works for any data type:
>>> foos=['foo']*8 >>> print foos ['foo', 'foo', 'foo', 'foo', 'foo', 'foo', 'foo', 'foo']
with a caveat. When building a new list by multiplying, Python copies each item by reference. This poses a problem for mutable items, for instance in a multidimensional array where each element is itself a list. You'd guess that the easy way to generate a two dimensional array would be:
listoflists=[ [0]*4 ] *5
and this works, but probably doesn't do what you expect:
>>> listoflists=[ [0]*4 ] *5 >>> print listoflists [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] >>> listoflists[0][2]=1 >>> print listoflists [[0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0]]
What's happening here is that Python is using the same reference to the inner list as the elements of the outer list. Another way of looking at this issue is to examine how Python sees the above definition:
>>> innerlist=[0]*4 >>> listoflists=[innerlist]*5 >>> print listoflists [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] >>> innerlist[2]=1 >>> print listoflists [[0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0], [0, 0, 1, 0]]
Assuming the above effect is not what you intend, one way around this issue is to use list comprehensions:
>>> listoflists=[[0]*4 for i in range(5)] >>> print listoflists [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] >>> listoflists[0][2]=1 >>> print listoflists [[0, 0, 1, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Operations on lists [edit]
List Attributes [edit]
To find the length of a list use the built in len() method.
>>> len([1,2,3]) 3 >>> a = [1,2,3,4] >>> len( a ) 4
Combining lists [edit]
Lists can be combined in several ways. The easiest is just to 'add' them. For instance:
>>> [1,2] + [3,4] [1, 2, 3, 4]
Another way to combine lists is with extend. If you need to combine lists inside of a lambda, extend is the way to go.
>>> a = [1,2,3] >>> b = [4,5,6] >>> a.extend(b) >>> print a [1, 2, 3, 4, 5, 6]
The other way to append a value to a list is to use append. For example:
>>> p=[1,2] >>> p.append([3,4]) >>> p [1, 2, [3, 4]] >>> # or >>> print p [1, 2, [3, 4]]
However, [3,4] is an element of the list, and not part of the list. append always adds one element only to the end of a list. So if the intention was to concatenate two lists, always use extend.
Getting pieces of lists (slices) [edit]
Continuous slices [edit]
Like strings, lists can be indexed and sliced.
>>> list = [2, 4, "usurp", 9.0,"n"] >>> list[2] 'usurp' >>> list[3:] [9.0, 'n']
Much like the slice of a string is a substring, the slice of a list is a list. However, lists differ from strings in that we can assign new values to the items in a list.
>>> list[1] = 17 >>> list [2, 17, 'usurp', 9.0,'n']
We can even assign new values to slices of the lists, which don't even have to be the same length
>>> list[1:4] = ["opportunistic", "elk"] >>> list [2, 'opportunistic', 'elk', 'n']
It's even possible to append things onto the end of lists by assigning to an empty slice:
>>> list[:0] = [3.14,2.71] >>> list [3.14, 2.71, 2, 'opportunistic', 'elk', 'n']
You can also completely change contents of a list:
>>> list[:] = ['new', 'list', 'contents'] >>> list ['new', 'list', 'contents']
On the right-hand side of assignment statement can be any iterable type:
>>> list[:2] = ('element',('t',),[]) >>> list ['element', ('t',), [], 'contents']
With slicing you can create copy of list because slice returns a new list:
>>> original = [1, 'element', []] >>> list_copy = original[:] >>> list_copy [1, 'element', []] >>> list_copy.append('new element') >>> list_copy [1, 'element', [], 'new element'] >>> original [1, 'element', []]
but this is shallow copy and contains references to elements from original list, so be careful with mutable types:
>>> list_copy[2].append('something') >>> original [1, 'element', ['something']]
Non-Continuous slices [edit]
It is also possible to get non-continuous parts of an array. If one wanted to get every n-th occurrence of a list, one would use the :: operator. The syntax is a:b:n where a and b are the start and end of the slice to be operated upon.
>>> list = [i for i in range(10) ] >>> list [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> list[::2] [0, 2, 4, 6, 8] >>> list[1:7:2] [1, 3, 5]
Comparing lists [edit]
Lists can be compared for equality.
>>> [1,2] == [1,2] True >>> [1,2] == [3,4] False
Sorting lists [edit]
Sorting lists is easy with a sort method.
>>> list = [2, 3, 1, 'a', 'b'] >>> list.sort() >>> list [1, 2, 3, 'a', 'b']
Note that the list is sorted in place, and the sort() method returns None to emphasize this side effect.
If you use Python 2.4 or higher there are some more sort parameters:
sort(cmp,key,reverse)
cmp : method to be used for sorting key : function to be executed with key element. List is sorted by return-value of the function reverse : sort(reverse=True) or sort(reverse=False)
Python also includes a sorted() function.
>>> list = [5, 2, 3, 'q', 'p'] >>> sorted(list) [2, 3, 5, 'p', 'q'] >>> list [5, 2, 3, 'q', 'p']
Note that unlike the sort() method, sorted(list) does not sort the list in place, but instead returns the sorted list. The sorted() function, like the sort() method also accepts the reverse parameter.
List methods [edit]
append(x) [edit]
Add item x onto the end of the list.
>>> list = [1, 2, 3] >>> list.append(4) >>> list [1, 2, 3, 4]
See pop(i)
pop(i) [edit]
Remove the item in the list at the index i and return it. If i is not given, remove the the last item in the list and return it.
>>> list = [1, 2, 3, 4] >>> a = list.pop(0) >>> list [2, 3, 4] >>> a 1 >>> b = list.pop() >>>list [2, 3] >>> b 4
operators [edit]
in [edit]
The operator 'in' is used for two purposes; either to iterate over every item in a list in a for loop, or to check if a value is in a list returning true or false.
>>> list = [1, 2, 3, 4] >>> if 3 in list: >>> .... >>> l = [0, 1, 2, 3, 4] >>> 3 in l True >>> 18 in l False
External links [edit]
- Python documentation, chapter "Sequence Types" -- python.org
- Python Tutorial, chapter "Lists" -- python.org