Lists can contain any mixture of values, including other lists.
For example, in
>>> L = [ 'Alice', 3.75, ['MATH', 'CSCI', 'PSYC' ], 'PA' ]
We will write code to print the courses, to change the math course to a stats course, and to append a zipcode.
The assignment operator does NOT create a new list. Rather it creates a new name for an existing list:
>>> L1 = [ 'cat', 'dog', 'ant', 'tiger', 'parrot' ]
>>> L2 = L1
>>> L1
['cat', 'dog', 'ant', 'tiger', 'parrot']
>>> L2
['cat', 'dog', 'ant', 'tiger', 'parrot']
>>> L1[2] = 'hawk'
>>> L1
['cat', 'dog', 'hawk', 'tiger', 'parrot']
>>> L2
['cat', 'dog', 'hawk', 'tiger', 'parrot']
Surprised? This is called an alias. Compare it with:
>>> S1 = 'this is a string'
>>> S2 = S1
>>> S1 = 'I changed the first string'
>>> S1
'I changed the first string'
>>> S2
'this is a string'
Python is designed to do this primarily for reasons of efficiency since
This is true for different data types as well.
If we want to copy a list we should use a special set of methods. We’ll see those next.
When variables are passed to functions, a copy of their value is created for numbers, strings, booleans:
def add_two(val1, val2):
val1 += val2
return val1
val1 = 10
val2 = 15
print val1, val2
print add_two(val1,val2)
print val1, val2
When lists are passed to functions, the parameter becomes an alias for the argument in the function call.
Here is an example of a function that returns a list containing the two smallest values in its input list:
def smallest_two(mylist):
mylist.sort()
newlist = []
if len(mylist) > 0:
newlist.append(mylist[0])
if len(mylist) > 1:
newlist.append(mylist[1])
return newlist
values = [35, 34, 20, 40, 60, 30]
print "Before function:", values
print "Result of function:", smallest_two(values)
print "After function:", values
In class we will discuss what happened
A common operation in programs is to go through every element in a list using a loop. While loops can always be used for this, but a for loop simplifies this operation significantly.
Let’s first go through all the animals in a list, and print them out.
animals = ['cat', 'monkey', 'hawk', 'tiger', 'parrot']
all_animals = ""
index = 1
for animal in animals:
animal = animal.capitalize()
all_animals += "%d. %s, " %(index, animal)
index += 1
print all_animals.strip()
We can understand what is happening by looking at this piece-by-piece:
Change the above code to capitalize all the animal names in the list.
Write a function to capitalize all the names in an input list.
Write a program to find the number of values greater than the average for the co2_levels given in the following list.
co2_levels = [ 320.03, 322.16, 328.07, 333.91, 341.47, \
348.92, 357.29, 363.77, 371.51, 382.47, 392.95 ]
Suppose you have the following pieces of code. Discuss what is different between the two.
mylist = [2,8,11]
for item in mylist:
item *= 2
mylist2 = [ [2], [8], [11] ]
for item in mylist:
item[0] *= 2
When you need to index a list, you need to generate numbers to serve as indices.
While solution:
animals = ['cat', 'monkey', 'hawk', 'tiger', 'parrot']
i = 0
while i < len(animals):
print animals[i]
i += 1
With a while loop, you have to be careful not to cause an infinite loop. You can also do the same with a special list of just consecutive numbers.
>>> range(len(animals))
[0, 1, 2, 3, 4]
Now, we can use the for loop as we have seen to achieve the same result.
animals = ['cat', 'monkey', 'hawk', 'tiger', 'parrot']
for i in range(len(animals))
print animals[i]
Note: no need to increment a counter anymore. We will see range in more detail next class.
Recall
>>> co2_levels = [ 320.03, 322.16, 328.07, 333.91, 341.47,
348.92, 357.29, 363.77, 371.51, 382.47, 392.95 ]
Now suppose we just want the values at indices 2, 3 and 4 of this in a new list:
>>> three_values = co2_levels[2:5]
>>> three_values
[328.07, 333.91, 341.47]
>>> co2_levels
[ 320.03, 322.16, 328.07, 333.91, 341.47, 348.92, 357.29, 363.77,
371.51, 382.47, 392.95 ]
We give the first index and one more than the last index we want
If we leave off the first index, 0 is assumed, and if we leave off the last index, the length of the list is assumed.
Negative indices are allowed — they are just converted to their associated positive values. Some examples:
>>> L1
['cat', 'dog', 'hawk', 'tiger', 'parrot']
>>> L1[1:-1]
['dog', 'hawk', 'tiger']
>>> L1[1:-2]
['dog', 'hawk']
>>> L1[1:-4]
[]
>>> L1[1:0]
[]
>>> L1[1:10]
['dog', 'hawk', 'tiger', 'parrot']
The most general form of slicing involves three values
L[si:ei:inc]
where
Any of the three values is optional
We’ll work through some examples in class to
Note: L[:] returns a copy of the whole list of L. This is the same using function list(L):
>>> L2 = L1[:]
>>> L2[1] = 'monkey'
>>> L1
['cat', 'dog', 'hawk', 'tiger', 'parrot']
>>> L2
['cat', 'monkey', 'hawk', 'tiger', 'parrot']
>>> L3 = list(L1)
>>> L3[1] = 'turtle'
>>> L1
['cat', 'dog', 'hawk', 'tiger', 'parrot']
>>> L2
['cat', 'monkey', 'hawk', 'tiger', 'parrot']
>>> L3
['cat', 'turtle', 'hawk', 'tiger', 'parrot']
Concatenation:
>>> v = [1,2,3]+[4,5]
>>> v
[1,2,3,4,5]
Replication:
>>> [1]*3
[1,1,1]
These are very similar to the analogous operations with strings.
What is the output of the following?
x = [6,5,4,3,2,1] + [7]*2
y = x
x[1] = y[2]
y[2] = x[3]
x[0] = x[1]
print x
y.sort()
print x
print y
Write a command to extract values from a list L0 indexed by 0,1,4,7 and 10,11, and return a list containing only these values.
Write a slicing command to extract values from a list L0 indexed by 1, 4, 7, 10, etc.
Version 1: use the function list to create a list of the characters in the string:
>>> s = "Hello world"
>>> t = list(s)
>>> print t
['H', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
Use the string split function, which breaks a string up into a list of strings based on the character provided as the argument.
We will play with the s = "Hello world" example in class.
What happens when we type the following?
>>> s = "Hello world"
>>> t = list(s)
>>> s1 = str(t)
This is unlikely to achieve what we want, which is usually the concatention of all of the strings in the list (assumming they are strings).
We will solve this problem using a for loop in the next exercise.
We can index strings:
>>> s = "Hello, world!"
>>> print s[5]
,
>>> print s[-1]
!
We can apply all of the slicing operations to strings to create new strings:
>>> s = "Hello, world!"
>>> s[:len(s):2]
'Hlo ol!'
Unlike lists, however, we can not use indexing to replace individual characters in strings:
>>> s[4] = 'c'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
Suppose you have the string
>>> s = "cat | dog | mouse"
and you’d like to have the list of strings
>>> L = [ "cat", "dog", "mouse"]
Splitting the list alone does not solve the problem. Instead, you need to use a combination of splitting, and a loop that strips off the extra space characters from each string and appends to the final result. Write this code. It should be at most 4-5 lines of Python.
Given a list
>>> L = [ 'cat', 'dog', 'tiger' ]
write a line of code to append the string 'lion'
Rewrite L so that it is a list of lists, with household pets in the 0th (sub)list, zoo animals in the first.
How can you append an additional list of farm animals (e.g. 'horse', 'pig' and 'cow') to L.
Write code to remove 'tiger' from the sublist of zoo animals.
Without typing into the Python interpreter, find the outputs from the following operations:
>>> x = ['a','b','c','d', 'e']
>>> print x
>>> for item in x:
... print "*%s*" %item,
...
>>> print x[3]
>>> x[3] = 3
>>> x
>>> len(x)
>>> x[2]=x[1]
>>> x
>>> x[5]
>>> y = x[1:4]
>>> y
>>> x
What about these operations?
>>> y = [1, 2, 3]
>>> y.append('cat')
>>> y
>>> y.pop()
>>> y
>>> y.remove(2)
>>> y
>>> y.remove('cat')
>>> z = ['cat','dog']
>>> z.insert(1,'pig')
>>> z.insert(0,'ant')
>>> z
>>> z.sort()
>>> z
>>> z1 = z[1:3]
>>> z1
>>> z
Write a function that returns a list containing the smallest and largest values in the list that is passed to it as an argument without changing the list? Can you think of ways to do this with sorting and without? Hint: use a for loop.