Week 6: Lists; More Functions
Week 6 Goals
-
Learn to represent data using lists
-
Learn about list indexing other operations
-
Learn how lists are used by functions
-
Learn how characters are represented using ASCII encoding
Get Week 6 In-class Code
To copy over the week 6 in-class example programs, do the following (If you have trouble with either of these steps, ask a Ninja or your professor for help):
-
Create a w06-lists subdirectory in your
cs21/inclass
directory, and cd into it:$ cd ~/cs21/inclass $ mkdir w06-lists $ cd w06-lists $ pwd /home/yourusername/cs21/inclass/w06-lists
-
Copy over the week 6 files into your
w06-lists
subdirectory (check that they copied successfully copied by runningls
:$ cp ~admin21/public/w06-lists/*.py ./ $ ls ascii.py biggest_circle.py largest.py lists.py list_functions.py
Week 6 Code
-
largest.py
: more practice with functions -
lists.py
: practice with lists and list operations -
list_functions.py
: practice with functions that use lists -
biggest_circle.py
: functions that use lists and graphics -
ascii.py
: examples of using character encoding
Week 6 Concepts
Lists
Until now, we have seen that a variable can hold a single value, e.g. if we set the variable x
equal to 5, then x
only holds the value 5.
A list is a variable that can hold multiple values, which are stored in an ordered manner.
In the following code, we use the bracket notation to create a list called nums
that holds the values 5, 6, 4, and 2, in that order:
nums = [5, 6, 4, 2]
print(nums) # prints [5, 6, 4, 2]
We can access individual elements of a list using a 0-based index:
nums = [5, 6, 4, 2]
print(nums[1]) # prints 6
nums[0] = 11
print(nums) # prints [11, 6, 4, 2]
We can also get the number of elements in a list using the len
function:
nums = [11, 6, 4, 2]
print(len(nums)) # prints 4
Working with Lists
We can iterate over the elements of a list in the same manner that we did with strings: either by iterating one element/character at a time, or by using the indices within the valid range to get each element/character by its index.
The following two for-loops produce the exact same output:
dogs = ['snoopy', 'bluey', 'pluto']
for dog in dogs:
print(dog + " is a good dog")
for i in range(len(dogs)):
print(dogs[i] + " is a good dog")
We can add elements to the end of a list using the append
method:
dogs = ['snoopy', 'bluey', 'pluto']
dogs.append('underdog')
print(dogs) # prints ['snoopy', 'bluey', 'pluto', 'underdog']
When are also able to concatenate two lists in order to create a larger list. Note that this does not change either of the two lists, but rather creates a new one:
weekdays = ['mon', 'tue', 'wed', 'thu', 'fri']
weekend = ['sat', 'sun']
week = weekdays + weekend
print(week) # prints ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']
Often we may want to start with an empty list, i.e. one containing no elements, and then add some number of elements to it. The following code asks the user how many elements to add, then appends elements as they are provided:
songs = []
n = int(input("How many favorite songs do you have? "))
for i in range(n):
song = input("Tell me one of your favorite songs: ")
songs.append(song)
print(songs) # prints all songs in the list
Passing Lists to Functions
Lists can be passed as arguments to function. The parameter of the function will refer to the entire list.
The following function calculates the sum of the values in the list that is passed as an argument:
def sum(lst):
total = 0
for i in range(len(lst)):
total = total + lst[i]
return total
An important difference between lists and other variables is that when a list is passed to a function, the function can modify the list, whereas it cannot modify arguments such as ints, floats, and strings.
For instance, consider the following function, which is attempting to change the value that is sent to it:
def change(x):
x = 0
Now let’s say we call this function as follows:
a = 5
change(a)
print(a) # prints 5
The code still prints 5, because the change
function has only changed the value of the parameter x
, not the value of the argument a
.
However, lists behave differently when passed to functions:
def change_list(lst):
lst[0] = 0
lst.append(17)
Now when we call this function, the list is changed:
nums = [5, 7, 9]
change_list(nums)
print(nums) # prints [0, 7, 9, 17]
This happens because the parameter lst
and the argument nums
are aliases for the same list.
This means that the list has two names: lst
and nums
.
Let’s take a look at the stack diagram to see why this happens!
First, here is what the stack diagram looks like for the code that calls change_list
: the nums
variable refers to the list containing [5, 7, 9]:
When change_list
is called, we pass nums
as the argument.
This means that the value in the box labeled nums
is copied to the box labeled lst
, i.e. the parameter of the change_list
function.
What’s in the box labeled nums
is the arrow pointing to the list, so now lst
has an arrow pointing to that list, too.
Now when change_list
runs the first line of code — lst[0] = 0
— we change what is in the box for element #0 of the list.
So the arrow now points to 0 instead of 5.
Next, when change_list
runs the second line of code — lst.append(17)
— a new box is added to the list, and it points to 17.
Finally, when change_list
returns and we go back to main
, the variable nums
is still pointing to the same list, which has been updated by change_list
.
This is why nums[0]
is now 0 instead of 5.
Character Encoding
Any piece of data that we use in our programs has two attributes: its value and its type.
For instance, if we have x = 8
, then the variable x
has the value 8 and the type "int".
Even the literal 1.7
has a value 1.7 and type "float".
The data’s value is always stored as a number, and the type determines which operations are legal and how they function.
But what about strings? For instance, how is "bingo" stored as a number?
Recall that a string is a sequence of individual characters, and though a string is not the same as a list, we can think of it as storing the individual characters "b", "i", "n", "g", and "o".
Then how are those characters' values stored as numbers?
To represent the individual characters, Python encodes them using an agreed-upon convention or standard that assigns numbers to individual characters, including letters of the alphabet but also punctuation, whitespace, and numerical characters such as "7"
.
A popular standard for encoding characters is ASCII, which was developed in the 1960s and is still commonly used today.
In Python, we can find the encoding of an individual character by using the ord(ch)
function, which returns the ASCII encoding of the character ch
:
letter = "k"
print(ord(letter)) # prints 107, which is the ASCII encoding of "k"
We can also go the other direction using the function chr(num)
, which returns the character that has num
as its encoding:
n = 63
print(chr(n)) # prints "?", which has 63 as its ASCII encoding