Tutorial, Part 4: Lists, for loops, built-in help, numpy, and intro to matplotlib

Contact: compwiki@physics.utoronto.ca
Last updated around: 2017-07-25
To finish our tutorial, we are going to introduce lists and for loops , which are loops(current link is for Python 2 documentation) that iterate over elements of lists(current link is for Python 2 documentation). We are also going to provide you with tips on how to further explore Python using its built-in help facilities.

1. Review

  • This section is still being revised.

2. A first introduction to lists

So far we have dealt with data values and data variables "one at a time", so to speak, so that each variable can only have one value at a time; for example the assignment statement x = 2 assigns the integer 2 to the variable x , and x = x + 1 updates the variable x to have the value 3.

But suppose we want to define a variable like a force vector or a collection of birthdays that we know consists of multiple components? In that case, it makes life easier to group several numbers (or strings, or even other variables) together into a single set with multiple components.

The Python set we'll use most often is the list, which is an ordered set in which Python keeps track of the position of each element in the set. A list is a comma-separated set of numbers (or strings, or other variables, or even other lists) enclosed by square brackets. Here is an assignment statement that creates a list assigned to the variable name my_list:
my_list = [1, 2, 3, 4, 5]
will result in
[1, 2, 3, 4, 5]
The variable my_list consists of five values. The first value is the integer 1, the second the integer 2, and so on. In Python, the first value of my_list is referenced using a special notation in which the index 0 corresponds to the first element, the index 1 corresponds to the second element, and so on, similar to the string example above. So my_list[0] corresponds to the value 1 and my_list[3] corresponds to the value 4. (For reasons we won't go into, several computer languages use this kind of zero-based indexing.) To see this indexing at work, look at the following example:
will result in
We can alter the values of the elements of the list:
my_list[0] = 10
will result in
[10, 2, 3, 4, 5]
Here we used the indexing to refer to a particular value, and then changed that value using an assignment statement.
  • (This will not work for strings.)
The following exercise will get you familiar with some of the basic properties of lists. Try the examples and create some of your own to better understand them. Our purpose here, in the spirit of the rest of the tutorial, is not to teach you everything there is to know about lists, but to focus on what you need to know to solve problems in physics. See the discussion of lists in the Python reference(current link is for Python 2 documentation)for more information.
Activity 1: Do the following:
  • Open up a Python shell and create a new list at the prompt
     my_list = [5, 4, 3, 2, 1, 0]

    and print it by typing my_list at the next prompt.
  • Print the first and third values of my_list with my_list[0] and my_list[2].
  • The last element of my_list can be referenced by typing my_list[-1], the second last element by typing my_list[-2], and so on. At the prompt, print the last, second last, and third last elements of my_list.
  • The second, third and fourth elements can be accessed as a list by typing my_list[1:4] . Print my_list[1:4] at the prompt now. You will see that a list is printed, so my_list[1:4] is itself a list. The : (colon) notation instructs the interpreter to create a list starting with index 1 (the second element) and ending with integer up to, but not including, 4. This integer is 3, which corresponds to the fourth element. (We know it's confusing, but there are good reasons for this approach.)
  • The length of my_list can be found by typing len(my_list) . Do this now at the prompt.
  • Create a new list
    my_new_list = ['apples', 'bananas', 'oranges']

    print it, and access the second element by typing my_new_list[1].
  • Here is practice with changing the values that appear within lists. Type the following:
    my_new_list[1] = 'grapes'
    my_list[0] = -9
  • You can concatenate lists --- stick them together --- using the + sign, and repeat them using the * sign. To see this, type the following and look at the results:
    my_list + my_list
    my_list * 2
    my_list * 5
    my_list + my_new_list

    The last example created a list of numbers and strings.

To finish this section, we will briefly describe the range() function, which creates a list of numbers separated by equal increments. For example, this example creates a list called my_range_list:
my_range_list = range(5)
print( my_range_list)
results in
[0, 1, 2, 3, 4]
Activity 2: Do the following:
  • Create a couple of lists using "range":
    a = range(10)
    b = range(10, 2, -2)
We will not say much more about range() here. Instead, we will now show you how to find out more about range and other Python functions, using Python's built-in help facilities.

3. Python's built-in help

Lists and the range() function are examples of powerful Python concepts that we can't cover comprehensively in this tutorial. How do you learn more about Python features? Here, we'll introduce you to the dir and help functions, which are built-in functions that document Python's features. Besides the built-in help, you should search through existing available on the web.

  • The dir function provides a list of features that apply to a list or any other Python variable, set, function, etc.. (Variables, sets, functions and so on are referred to as Python objects). Here is an example that uses dir on a list you've created
    a = [2, 3, 5, 10, 12]
This will produce a list in alphabetical order of "methods" --- functions ---- that apply to a. Now, you will see if you type this example that a very long list of methods is produced; there is no way you can understand what a particular method does just by the name. You can type the dir() function for any Python object, and get a list of methods that apply to it. To get help on any of the listed methods, type


To use a typical method, type


where <args> represents any arguments to the function.
To see help in action, type help(range) at the prompt.
Activity 3: Here's an example of discovering Python operations that apply to a given list within an interactive session. Look at the session excerpt below. We'll explain what's going on after we present the example, but try and understand what's happening as you read through it.

In [18]: d = ['a', 'b', 'c', 'pi', 3.14, 2**0.5, 14]
In [19]: dir(d)
In [20]: help(d.append)
Help on built-in function append:
append(...) method of builtins.list instance
L.append(object) -> None -- append object to end
In [21]: d.append(15)
In [22]: d
Out[22]: ['a', 'b', 'c', 'pi', 3.14, 1.4142135623730951, 14, 15]
In [23]: help(d.reverse)
Help on built-in function reverse:
reverse(...) method of builtins.list instance
L.reverse() -- reverse *IN PLACE*
In [24]: d.reverse()
In [25]: d
Out[25]: [15, 14, 1.4142135623730951, 3.14, 'pi', 'c', 'b', 'a']
Here's what happens:
  1. We start by creating a list of strings and numbers d .
  2. We then ask what kind of operations can be applied to d ( dir(d) ). The result is a list of methods; for now we'll ignore the ones that are marked by double underscores like __add__ ; and use the standard methods such as pop .
  3. We see that there is a function ("method") called append , and ask for help on this method ( help(d.append) ).
  4. We then append the number 15 to d ( d.append(15) ), and print out the new d , which has 15 tagged on the end.
  5. We then ask for help on the reverse function ( help(d.reverse) ).
  6. We then reverse d using d.reverse() , and print out the new d . Notice that order of the elements in d has been reversed.

4. The for loop

In Part 3, we introduced the while loop that continues executing as long as a condition is True. The for loop is another kind of loop that iterates over values in a list. This is best explained by example:
#Create a list from 0 to 9
a = range(10)
print("a is ", a)
#Iterate over the values in "a"
for val in a:
    #As for previous statements (if, while, etc.) the blocks are denoted by indentation.
    print "The current value is ", val
    if val>5:
        print "This value is greater than 5"
        print "The square of this value is", val**2
print "Done."

5. Numpy and numpy arrays

We will be making a great deal of use of the array structures found in the numpy package. These arrays are used in many python packages used in computational science, data analysis, and graphical analysis (in packages like scipy and matplotlib).

Numpy arrays are a type of highly structured list that you can use for doing common numerical and matrix calculations.
  • While there are exceptions, numpy arrays are a special kind of list with a constrained size and with all entries having the same type.
  • Numpy arrays make it easy to set up vectors, matrices, and higher order tensor objects for further manipulation.
  • Importantly, Python has optimized its handling of numpy arrays to carry out calculations very quickly and efficiently.
  • All told, hey are very handy for computational physics.

To created numpy arrays, we first need to import the numpy module as follows: either
import numpy as np
which is preferable, or, more conveniently
from numpy import *
  • The first statement serves to change numpy to a short form np. Then individual methods and objects within numpy can be referred to as follows: np.sin(), np.pi, etc..
  • The second statement imports everything related to numpy and allows you to simply use sin(), pi, etc..
  • The first statement is preferable because it is easier to tell what the origin of the methods and objects you will use in your codes is.
Activity 4: Do the following:
  • Enter the following commands one at a time and examine the output:
    import numpy as np
    a = np.array([0,10,20,30,40])
    a[1] = 15
    b = np.arange(-5, 5, 0.5)
    b ** 2

  • The output from the session is
    In [4]: import numpy as np
    In [5]: a = np.array([0,10,20,30,40])
    In [6]: a
    Out[6]: array([ 0, 10, 20, 30, 40])
    In [7]: a[:]
    Out[7]: array([ 0, 10, 20, 30, 40])
    In [8]: a[1:3]
    Out[8]: array([10, 20])
    In [9]: a[1] = 15
    In [10]: a
    Out[10]: array([ 0, 15, 20, 30, 40])
    In [11]: b = np.arange(-5, 5, 0.5)
    In [12]: b
    Out[12]: array([-5. , -4.5, -4. , ...,  3.5,  4. ,  4.5])
    In [13]: b**2
    Out[13]: array([ 25.  ,  20.25,  16.  , ...,  12.25,  16.  ,  20.25])
    In [14]: 1/b
    __main__:1: RuntimeWarning: divide by zero encountered in true_divide
    array([-0.2       , -0.22222222, -0.25      , ...,  0.28571429,
            0.25      ,  0.22222222])
    In [20]: b[10]
    Out[20]: 0.0
    In [21]: 1/b[10]
    __main__:1: RuntimeWarning: divide by zero encountered in double_scalars
    Out[21]: inf
Now do the following:
  • Look carefully at the output of the arange command, and make sure you understand it. To get more explanation on arange , type help(arange) .
  • Notice that operations on numpy arrays act on each element in the array. So b**2 has the effect of raising to the power of two each element in the array.
  • Notice that the divide by zero in the 1/b command results in an "Inf" output, located at element [10].
  • You can practice further with numpy arrays. For example, create another array c=0.5*b, and then type b + c. Notice that for numpy arrays, b + c is not a concatenation of two lists, as in our previous discussion of lists, but the sum of the elements of b and c. ( This example shows how Python interprets operators like + in the context of the operands, i.e. the objects that are involved in the operation. This reflects the object oriented character of Python.)

Activity 5: To further practice using numpy arrays, do the following example:
  • Suppose an object under the influence of gravity and resistive drag falls with a downward velocity

    where s_t = 20 m/s is the terminal speed and tau = 5 s is a time constant.
  • Write a program to write the acceleration and position of the object every half second for 20 seconds. Assume the initial position x(0)=0. (We will use this example to illustrate a few other ideas after we're done.)
  • We first find analytic expressions for the position and acceleration. Given the velocity, the position and acceleration are obtained from integration and differentiation by:

    Our script imports numpy and defines a time array t with the following line:
    t = arange(0,20.5,0.5)
  • Another standard trick is to create a for loop that will run over an index that extends from the beginning to the end of an array. For example, to create a code that prints the elements of t[:] , we write
    for j in range(len(t)): print(t[j])
  • To make sure you understand the previous line code example: len(t) is the length of the array t , which is 41. range(len(t)) is an array of integers [0, 1, 2 ..., 39, 40] .The for header creates a variable j that iterates over range(len(t)). In the body of the loop, t[j] is the j th value of t.
  • Now go ahead and produce a solution on your own, then check your answer against this script, which you can download and run.

6. Introduction to plotting with matplotlib

To finish off this tutorial, let's do some simple plotting using the matplotlib module of python. We will define and plot a time array and couple of trigonometric functions of time.
  • Matplotlib also makes use of numpy arrays and hence inherits numpy methods. In the code below we've chosen a particular way of importing these methods, but you can choose other approaches if you'd prefer.
    #import pylab - which includes the matplotlib library
    import pylab as plt
    import numpy as np
    #define pi
    pi = np.pi
    #define a time array. This array runs starts from 0, runs in increments of pi/100, and stops at 4*pi-pi/100.
    t = np.arange(0, 4*pi, pi/100)
    #define an array that represents the sine of t
    sin_t = np.sin(t)
    #define an array that represents the cosine of t
    cos_t = np.cos(t)
    #Use the matplotlib plot function to plot both cos(t) and sin(t)
    plt.plot(t, sin_t, t, cos_t)
    #add a title
    plt.title('sin and cosine')
    #add a label on the x axis
    plt.xlabel('Time (s)')
    #add a label on the y axis
    plt.ylabel('sin(t), cos(t)')
    #create a legend displaying the functions
    plt.legend(('sin(t)', 'cos(t)'))
    #You often need to include this line at the end of any matplotlib script, or you won't see the plotting window
  • Copy/paste the above into Spyder, and run it. You should see an image like the following:
Activity 6: Do the following:
  • The previous example introduced several new functions: plot , title , xlabel , etc..
  • Find out more about these functions by importing pylab again and typing help(plot) , help(title) , etc.. in the Python Shell. We will explore these functions in more detail in the Learning Physics with Pylab (current link is for Python 2 documentation) tutorial.

7. Recap

This concludes the Part 4 of the tutorial. In summary:
  1. We have learned about lists like a=[1,2,3,4] and numpy arrays, and what kind of operations can be done on them.
  2. We have learned how to explore possible actions on an object with dir(my_object) and help(my_object.method)
  3. We have learned about for loops, which iterate over a list.
  4. We have begun to explore visualization with pylab.

We have also discussed a few examples of problem solving. The strategy we use is to
  1. Come up with some clearly written formulas that you want to code up on a computer.
  2. Include a lot of comments in the code.
  3. Include helpful hints on input (like descriptive prompts) and on output.

We hope that this tutorial has helped start you on the path to doing physics with computers. Please speak to your instructor if you have any suggestions for how to improve this tutorial.

(current link is for Python 2 documentation)

(current link is for Python 2 documentation)
This concludes part 4 of the tutorial.