Getting Started in Python
2.2 Using Objects: the list Class
2.2.4 Constructing Lists
Python’s lists support many other behaviors; we will introduce several more in the coming section. But before we go further, we would like to describe several convenient ways to construct a list. We have already demonstrated one approach, which is to create an initially empty list with the syntaxlist( )and subsequently populate the list using theappendand insertmethods. But this style is cumbersome for initializing longer lists. When the initial contents of a list are known in advance, a more convenient approach is to use a literal form to instantiate a list, as shown here.
>>> favoriteColors = ['red', 'green', 'purple', 'blue']
This form should seem familiar; it is precisely that which Python used when displaying a list to us. Square brackets delimit the list, with individual elements of the list separated by commas. The literal form can even be used when creating an empty list.
>>> groceries = []
Although the syntaxgroceries = list( )more clearly designates the new object as a list, the literal form is the one used more commonly by Python programmers (primarily because it involves less typing).
Copying an existing list
By default the syntaxlist( )is used to construct an initially empty list. However, a new list can be created that is a copy of an existing list. This is done by sending the existing list as a parameter to the constructor. For example, based on thefavoriteColorslist we created a moment earlier, we can do the following:
>>> primaryColors = list(favoriteColors)
>>> primaryColors.remove('purple')
>>> favoriteColors
['red', 'green', 'purple', 'blue']
>>> primaryColors
['red', 'green', 'blue']
The expressionlist(favoriteColors)creates a brand newlistinstance, yet one that has the same contents. After the new list is constructed, those two lists are independent objects rep-resented in memory and can be manipulated separately. Notice that removing 'purple' from the copy did not have any effect on the original list.
The range function
Lists are often used to represent a range of integers. Python supports a built-in function rangeto help construct such lists. There are three different forms for its use. The simplest formrange(stop)takes a single parameter and constructs a list of numbers starting at zero and going up to but not includingstop.
>>> range(5) [0, 1, 2, 3, 4]
This convention is intentionally designed to be consistent with the zero-indexing of lists in Python. We will see the advantage of this choice in later uses ofrange. There is also a two parameter formrange(start, stop)that constructs a list of integers starting atstartand going up to but not includingstop.
>>> range(23, 28) [23, 24, 25, 26, 27]
A third formrange(start, stop, step)results in a list starting atstart, advancing by the given step size so long as it does not reach or pass the given stopping value. The step size can be positive or negative, as shown below.
>>> range(100, 130, 4)
[100, 104, 108, 112, 116, 120, 124, 128]
>>> range(8, 3, -1) [8, 7, 6, 5, 4]
The list produced byrangegoes up to, but does not include, the specified stopping value. Thusrange(5, 8)produces the list[5, 6, 7].
2.2.5 Operators
Thus far, we have suggested that all of an object’s behaviors are invoked by means of a method call. Technically this is true, but some behaviors are so commonly used that Python supports a more convenient syntax that we call an operator.
For the sake of example, suppose that we have a list of people from a race, which is sorted from fastest to slowest finishers, and thatcontestantsis our identifier. We have seen how to display the entire list in the interpreter. But that list may be very long. What if we wanted to access one particular entry of the list? We can use an index as the natural way to describe the position of interest. For example the bronze medalist is the third-fastest finisher, and thus at index2of the list. We can access that particular element of the list using the syntaxcontestants[2]as shown in the following session:
>>> contestants = ['Gomes', 'Kiogora', 'Tergat', 'Yego']
>>> contestants[2]
'Tergat'
This use of square brackets is typically called indexing the list. The square brackets serve an entirely different purpose than the parentheses that are used to enclose parameters when invoking a method. In the above example, we did not specify a method name, just the identifier for the list itself. The developers of Python could have supported such queries using a method-calling syntax, perhaps ascontestants.getItem(2). Yet because accessing an element of a list is such a common task, their goal was to provide a simpler syntax.1 List indexing can also be used to replace an existing element of a list with another. This is done by using the square bracket notation on the left-hand side of an assignment statement, as shown here.
>>> groceries = ['cereal', 'milk', 'apple']
>>> groceries[1] = 'soy'
>>> groceries
['cereal', 'soy', 'apple']
The second line has the effect of replacing the element originally at index 1 of the list, namely replacing 'milk' with 'soy'. For convenience, Python also allows the use of negative indices, which are interpreted relative to the end of the list. The index−1denotes the last position of the list,−2the second-to-last and so forth.
>>> contestants = ['Gomes', 'Kiogora', 'Tergat', 'Yego']
>>> contestants[-1]
'Yego'
>>> contestants[-4]
'Gomes'
>>> contestants[-2]
'Tergat'
Based upon the conventions, positive indices can range from zero up to one less than the length of the list, whereas negative indices range from−1down to the negative length of the list. Python also supports access to a larger portion of a list using a syntax known as slicing, which we discuss in more detail in Section 2.3.
Behind the scene, syntactic shorthands such as these are translated back to standard method calls. For example, the shorthandcontestants[2]is technically translated to a call of the formcontestants. _ _ getitem _ _ (2). The shorthandgroceries[1] ='soy'is translated to a method call of the formgroceries. _ _ setitem _ _ (1,'soy'). At this time, there is little need to focus on these underlying method calls, but we mention this in passing because you may see names such as _ _ getitem _ _ when viewing Python documentation. We will investigate such special methods far more thoroughly when it comes time to implement our own classes in Chapter 6.
1. Not coincidentally, the use of square brackets for indexing stems from the same convention used in many earlier programming languages.