|From The Quick Python Book, Third Edition by Naomi Ceder
Understanding how list indices and lists work in Python makes the language a lot more useful. This article excerpt discusses list indices and modifying lists in Python.
Understanding how list indices work makes Python much more useful.
Elements can be extracted from a Python list using a notation like C’s array indexing. Like C and many other languages, Python starts counting from zero; asking for element zero returns the first element of the list, asking for element one returns the second element, and so forth. Here are a few examples:
>>> x = ["first", "second", "third", "fourth"] >>> x 'first' >>> x 'third'
But Python indexing is more flexible than C indexing; if indices are negative numbers, they indicate positions counting from the end of the list, with negative one being the last position in the list, negative two being the second-to-last position, and so forth. Continuing with the same list x, we can do the following:
>>> a = x[-1] >>> a 'fourth' >>> x[-2] 'third'
For operations involving a single list index, it’s generally satisfactory to think of the index as pointing at a specific element in the list. For more advanced operations, it’s more correct to think of list indices as indicating positions between elements. In the list
["first", "second", "third", "fourth"], you can think of the indices as pointing like this:
This is irrelevant when you’re extracting a single element, but Python can extract or assign to an entire sublist at once – an operation known as slicing. Instead of entering
list[index] to extract the item after
list[index1:index2] to extract all items including
index1 and up to (but not including)
index2 into a new list. Here are some examples:
>>> x = ["first", "second", "third", "fourth"] >>> x[1:-1] ['second', 'third'] >>> x[0:3] ['first', 'second', 'third'] >>> x[-2:-1] ['third']
It may seem reasonable that if the second index indicates a position in the list before the first index, this would return the elements between those indices in reverse order, but this isn’t what happens. Instead, this returns an empty list:
>>> x[-1:2] 
When slicing a list, it’s also possible to leave out
index2. Leaving out
index1 means “go from the beginning of the list,” and leaving out
index2 means “go to the end of the list”:
>>> x[:3] ['first', 'second', 'third'] >>> x[2:] ['third', 'fourth']
Omitting both indices makes a new list that goes from the beginning to the end of the original list; it copies the list. This is useful when you wish to make a copy that you can modify, without affecting the original list:
>>> y = x[:] >>> y = '1 st' >>> y ['1 st', 'second', 'third', 'fourth'] >>> x ['first', 'second', 'third', 'fourth']
Try This: list slices and indexes
Using what you know about the len() function and list slices, how would you combine the two to get the second half of a list when you don’t know what size the list is? Experiment in the Python shell to confirm if your solution works.
You can use list index notation to modify a list as well as to extract an element from it. Put the index on the left side of the assignment operator:
>>> x = [1, 2, 3, 4] >>> x = "two" >>> x [1, 'two', 3, 4]
Slice notation can be used here too. Saying something like
lista[index1:index2] = listb causes all elements of
index2 to be replaced with the elements in
listb can have more or fewer elements than are removed from
lista, in which case the length of
lista is altered. You can use slice assignment to do several different things, as shown here:
>>> x = [1, 2, 3, 4] >>> x[len(x):] = [5, 6, 7] ❶ >>> x [1, 2, 3, 4, 5, 6, 7] >>> x[:0] = [-1, 0] ❷ >>> x [-1, 0, 1, 2, 3, 4, 5, 6, 7] >>> x[1:-1] =  ❸ >>> x [-1, 7]
❶ Appends list to end of list
❷ Appends list to front of list
❸ Removes elements from list
Appending a single element to a list is such a common operation that there’s a special
append method to do it:
>>> x = [1, 2, 3] >>> x.append("four") >>> x [1, 2, 3, 'four']
One problem can occur if you try to append one list to another. The list gets appended as a single element of the main list:
>>> x = [1, 2, 3, 4] >>> y = [5, 6, 7] >>> x.append(y) >>> x [1, 2, 3, 4, [5, 6, 7]]
extend method is like the
append method, except that it allows you to add one list to another:
>>> x = [1, 2, 3, 4] >>> y = [5, 6, 7] >>> x.extend(y) >>> x [1, 2, 3, 4, 5, 6, 7]
insert method allows you to insert new list elements between two existing elements or at the front of the list.
insert is used as a method of lists and takes two additional arguments; the first is the index position in the list where the new element should be inserted, and the second is the new element itself:
>>> x = [1, 2, 3] >>> x.insert(2, "hello") >>> print(x) [1, 2, 'hello', 3] >>> x.insert(0, "start") >>> print(x) ['start', 1, 2, 'hello', 3]
insert understands list indices in its own way, but for most uses it’s easiest to think of
list.insert(n, elem) as meaning
insert elem prior to the nth element of list.
insert is a convenience method. Anything that can be done with
insert can also be done using slice assignment;
list.insert(n, elem) is the same thing as
list[n:n] = [elem] when
n is non-negative. Using
insert makes for more readable code, and
insert even handles negative indices:
>>> x = [1, 2, 3] >>> x.insert(-1, "hello") >>> print(x) [1, 2, 'hello', 3]
del statement is the preferred method of deleting list items or slices. It doesn’t do anything that can’t be done with slice assignment, but it’s usually easier to remember and easier to read:
>>> x = ['a', 2, 'c', 7, 9, 11] >>> del x >>> x ['a', 'c', 7, 9, 11] >>> del x[:2] >>> x [7, 9, 11]
del list[n] does the same thing as
list[n:n+1] = , whereas
del list[m:n] does the same thing as
list[m:n] = .
remove method isn’t the converse of
insert inserts an element at a specified location,
remove looks for the first instance of a given value in a list and removes that value from the list:
>>> x = [1, 2, 3, 4, 3, 5] >>> x.remove(3) >>> x [1, 2, 4, 3, 5] >>> x.remove(3) >>> x [1, 2, 4, 5] >>> x.remove(3) Traceback (innermost last): File "<stdin>", line 1, in ? ValueError: list.remove(x): x not in list
remove can’t find anything to remove, it raises an error. You can catch this error using the exception-handling abilities of Python, or you can avoid the problem by using
in to check for the presence of something in a list before attempting to remove it.
reverse method is a more specialized list modification method. It efficiently reverses a list in place:
>>> x = [1, 3, 5, 6, 7] >>> x.reverse() >>> x [7, 6, 5, 3, 1]
Try this: Modifying lists
Suppose you have a list which is ten items long. How might you move last three items from the end of the list to the beginning, keeping them in the same order?
That’s all for lists!