VPython Lists

From Physics Book
Jump to navigation Jump to search

This page is to help students that are inexperienced with coding learn about the basic concepts of lists.

Lists are one of the most, if not the most, ubiquitous and powerful tools in Python. Their usefulness comes from the fact that they can be used to hold any amount of data and that data can be of any type. As such, lists are generally the go-to method for storing information.


Types of Lists

Lists of Numbers

The most basic list is one that has numbers in it. The list of numbers may contain integers, floats, or both.

Example:

numList = [1,2,3.4,5]

Lists of Strings

Lists can also be comprised of words (strings). These words must have "" surrounding them for the word to be considered a string and for the computer to accept it.

Example:

strList = ["lists", "are", "super", "cool"]

Lists of Complex Data Types

The above examples provide insight into creating lists of simple Python data types such as ints, strings, and floats. However, one of the most common uses of lists is to store more complex, custom data types. A good example of using a list in this manner in physics lab might be to store a number of spheres. A case where this may come in handy is when writing a program that models the effects of gravity on three differently sized balls. One way to initialize the three spheres is to create them individually as such:

smallBall = sphere(pos=vector(-30, 0, 0), radius=1, color=color.blue)
mediumBall = sphere(pos=vector(0, 0, 0), radius=5, color=color.red)
largeBall = sphere(pos=vector(30, 0, 0), radius=10, color=color.green)

Another method would be to use a list. Here's what that might look like:

balls = [sphere(pos=vector(-30, 0, 0), radius=1), sphere(pos=vector(0, 0, 0), radius=5), sphere(pos=vector(30, 0, 0), radius=10)]

Both examples will allow us to work with the spheres, however we gain the important advantage of being able to use a loop with the second implementation. Consider the scenario where we want to update the location of each of the three balls. If a list is not being used to store the spheres, then each of the three locations will have to be updated manually:

smallBall.pos = smallBall.pos - 2
mediumBall.pos = mediumBall.pos - 2
largeBall.pos = largeBall.pos - 2

However, by using a list to store the data, we can employ a simple for loop to update the locations:

for ball in balls:
    ball.pos = ball.pos - 2

In many cases, the programs you write in lab can have dozens of spheres. In that case, using a list to store the spheres will save you a great deal of time and effort.

Lists of Mixed Data Types

Lists don't have to be made up of the same data type.

For example, the following list made up of both strings and numbers is a valid list.

mixedList = ["twenty", 20, 5,"five"]

Lists of Lists

Lists can also contain lists within themselves. These are called nested lists.

Example:

nestedList = [1,"nest",[1,2]]

Since python does not have a matrix data structure, nested lists are commonly used to represent matrices. For example, a 3 x 3 matrix can be represented in python as a list of three elements where each of those elements is another list that corresponds to a row in the matrix.

For example, consider the following 3 x 3 matrix:

[math]\displaystyle{ \begin{bmatrix} 5 & 12 & 1 \\ 23 & 9 & 73 \\ 0 & 61 & 2 \end{bmatrix} }[/math]

We can represent the above matrix using nested lists as such:

matrix = [[5, 12, 1],[23, 9, 73],[0, 61, 2]]

Empty Lists

Empty nests are commonly used to initialize a variable and avoid program errors when calling upon that empty list. They generally have data added to them and grow throughout the program.

Example:

emptyList = []

An example of a situation in which you might initialize an empty list in Physics lab is when initializing a number of spheres and storing them in a list. By using a list and a loop, you can avoid writing an individual line of code for each sphere. Example:

spheres = []
numSpheres = 5000
for i in range(numBalls):
    spheres.append(sphere(pos=vector(i, i, i), radius=i, color=color.green))

Properties of Lists

Indices

Indexing a list is how we can identify the value at a certain spot in the list. The first component of the list is the 0th index and then it goes up by one until the last component (the nth-1 index in an list of length n). When trying to find the nth index, we use this notation: listName[n]

For example, consider the following list:

nums = [47,36,11,19]

The following commands allow us to get access to the individual list elements:

nums[0]   # returns 47 
nums[1]   # returns 36
nums[2]   # returns 11
nums[3]   # returns 19

Indexing into nested lists follows the same logic as indexing into one dimensional lists.

For example, consider the following nested list:

matrix = [[5, 12, 1],[23, 9, 73],[0, 61, 2]]

This list has three elements, each of which is another list. It follows then that:

matrix[0] returns [5, 12, 1]

To obtain an individual element in a nested list, we simply index twice:


matrix[0][0]   # returns 5
matrix[0][1]   # returns 12
matrix[0][2]   # returns 1


Appending to a List

The append function takes a previously defined/calculated value and adds it to a pre-existing list. This generally occurs in a loop and is very useful when you are trying to find patterns in the behavior of a non-static variables.

Example Code:

emptyList = []
t = 0
while t < 10:
  t = t + 1
  emptyList.append(t)
print(emptyList)              # Prints out [1,2,3,4,5,6,7,8,9,10]

Other Useful List Functions

To obtain the length of a particular list, use the len() function:

aList = [4, 5, 12]
numElements = len(aList)
print(numElements)            # Prints out 3

To obtain the sum of the elements of a list, use the sum() function:

aList = [1, 2, 3]
print(sum(aList))             # Prints out 6

A common scenario in which the above two functions are very useful is finding the average of the elements in a list:

aList = [0, 5, 15]
avg = sum(aList)/len(aList)
print(avg)                    # Prints out 20

To reverse the elements in a list, use the reverse() function:

aList = [1, 2, 3]
aList.reverse()
print(aList)                  # Prints [3, 2, 1]

Note that the reverse() function does not return a new list, instead it directly modifies the content of the list it is called on.

Sometimes you may need to remove an item from a list. Use the remove() function to do this:

aList = [7, 1, 3]
aList.remove(7)
print(aList)                  # Prints [1, 3]
print(len(aList))             # Prints 2


Using Loops with Lists

Basics Of While Loops and Lists

Lists are great by themselves for storing data. But when you want to use that data efficiently, you need loops.

In this example, we are going to use a simple while loop to change a set of test scores using a while loop:

 testScores = [76, 54, 68, 77]     ## the list you are using
 listSize = len(testScores)     ## the size of the list
 loopCount = 0     ## this is the variable that will progress in the loop
 while (loopCount < listSize):     ## starts your loop
     testScores[loopCount] = 100    ## changes each test score to 100
     loopCount = loopCount + 1    ##updates loopCount so we can work on the next element
 print(testScores)    ##displays the test scores

This is an efficient way to do the same thing to all of the elements in you list.

Common Errors

The most common mistake when using lists and loops is indexing your list outside of it's bounds.

 while (loopCount <= listSize):     ## notice the  <=

If you use this, your program will fail and encounter an index out of range error. This is because listSize is the number of elements in your list, but as you'll recall, the last element in a list actually has an index 1 less than the list's size. In this loop, the code will try to run until loopCount equals listSize, but when they are equal, the code tries to index the list where it does not exist.


Another common error comes when you start a loop at 1 instead of 0.

 loopCount = 1     
 while (loopCount < listSize):    

In this instance, your code will skip the first element of your list. If you did not want to do anything with that element, then this is fine. More often than not, however, you will want to index all elements.

Advantages of While Loops

While loops are nice because you can pick and chose which indexes you want to use. In For Each Loops, the same code will run over each element of a list. Using a counter and while loop, however, you can do things like only taking every other index.

 while (loopCount < listSize):     
     ##your code here
     loopCount = loopCount + 2     

If you wanted, you could also start from the back of the list and work forwards.

 loopCount = listSize     
 while (loopCount - 1 >= 0):  
     ##your code here
     loopCount = loopCount - 1  

Another useful trick with while loops involves using indexes around loopCount to do different things.

 while (loopCount < listSize - 1):    
     yourList[loopCount] = yourList[loopCount + 1] -1   
     


Relation to PHYS 2212

Imagine you are trying to detect a pattern in the speed of a moving electron in a 30 second span of time. The code you write calculates on a loop a numerical value of the speed of the electron every second. You previously defined an empty list (elecSpeed = []). The append function takes the result calculated (Let's call this x) by the program and adds it to the list that is being appended. By putting this line of code inside of the loop, your program can create a list containing 30 calculated speeds of the electron from time t = 0 to t = 29.

Example code:

elecSpeed = []
while t < 30:
    CODE THAT CALCULATES SPEED, x
    elecSpeed.append(x)

RESULTS: elecSpeed = [x(at time t=0),x(at time t=1),x(at time t=2),..........x(at time t=29)]


Further Reading

http://openbookproject.net/thinkcs/python/english3e/lists.html

References

http://openbookproject.net/thinkcs/python/english3e/lists.html