List Operations
There are many built-in operations on lists. Here are a few of the most useful ones here.
-
.append()
: The append method adds a new element to the end of a list. The append method mutates the list that it is invoked on, it does not create a new list. The syntax for the append method is:<list>.append(<element>)
For example, assume you want to end up with four cartoons in your list, instead of just three:
cartoons = ['Tom', 'Jerry', 'Droopy'] cartoons.append('Dog') ['Tom', 'Jerry', 'Droopy', 'Dog']
-
Concatenation: The
+
operator can be used with lists and is very similar to how it is used to concatenate strings. It produces a new list, it does not mutate either of the input lists.<list> + <list> -> <list>
For example,
[0, 1] + [2, 3] -> [0, 1, 2, 3]
-
Length: The
len
operator can be used to find out the length of an object. Thelen
operator works for many things other than lists, it works for any object that is a collection of things including strings. The output from len is the number of elements in its input.len(<list>) -> <number>
For example,
len([0, 1])
will return2
. Note thatlen
only counts the outer elements:print(len(['a', ['b', ['c', 'd']]])) # -> 2
Since the input list contains two elements:
'a'
and['b', ['c', 'd']]
. When you invokelen
on a string, the output is the number of elements in the string.print(len("dsquare")) # -> 7
Quiz 3.8
What is the value of len(p)
after running the following code:
p = [1, 2]
p.append(3)
p = p + [4, 5]
len(p) # -> ?
Answer
5
Let's run through this code line by line so that you know exactly what is going on.
The first line assigns p
to a list. The next statement invokes append
on p
, passing in the value 3
, adding it to the end of the list.
Then, the +
operator creates a new list combining the two operands, p
and another list, which becomes the new list object assigned to p
.
The length of the new list object is five.
Quiz 3.9
What is the value of len(p)
after running:
p = [1, 2]
q = [3, 4]
p.append(q)
len(p) # -> ?
Answer
3
The first statement creates the list with the elements, 1
and 2
, and assigns that list to the variable p
.
The second statement creates a list with the elements, 3
and 4
, and assigns that list to the variable q
.
The append statement adds just one new element to p
, the list object q
. Try this in your interpreter to see how it looks when you print p
.
p = [1, 2]
q = [3, 4]
p.append(q)
print(len(p)) # -> 3
print(p) # -> [1, 2, [3, 4]]
Loops on Lists
Since lists are collections of things, it is very useful to be able to go through a list and do something with every element. In Unit 2, we introduced the while loop:
while <TestExpression>:
<Block>
If the test expression is True
, the <Block>
is executed. At the end of the block, execution continues by re-evaluating the test expression, and continuing to execute the block as long as the test expression evaluates to true.
Quiz 3.12
Define a procedure called print_all_elements
that takes as input a list p
and prints out every element of that list. Here is a start:
def print_all_elements(p):
i = 0
while __________:
print(p[i])
i = i + 1
Answer
When the procedure starts p
refers to some list that was passed in, and since we want the procedure to work on any list there is no need to assume anything about the list. Since i
has the value zero, it means that the value of p
index i
is the first element of the list p
. In the loop body, this value is printed, print(p[i])
, and then move on to the next element by increasing i
by one, i = i + 1
. This will continue for each element of the list.
Now, what you need for the test condition of the while loop is to figure out when to stop. Recall that the len
operator tells you the length of a list. The highest index in the list is the value of len(p) - 1
. So, we want the test condition of the loop to make sure that i
has not exceeded that last index. Here is one way to write that condition:
i <= len(p) - 1
which is equivalent to a simplier expression:
i < len(p)
We can write the final code as:
def print_all_elements(p):
i = 0
while i < len(p):
print(p[i])
i = i + 1
for
Loops
In Python there is a more convenient way to loop through the elements of a list: the for
loop. The syntax looks like this:
for <name> in <list>:
<block>
The loop goes through each element of the list in turn, assigning that element to the <name>
and evaluating the <block>
. Using the for
loop, we can use less code than we needed using the while loop to define the procedure print_all_elements
:
def print_all_elements(p):
for e in p:
print(e)
Let's walk-through what happens when you apply this for loop to a list:
mylist = [1, 2, 3]
print_all_elements(mylist)
When you pass in mylist to print_all_elements the variable p will refer to the list that contains the three elements, 1
, 2
and 3
. When the loop is executed, the variable e is assigned to the first element in the list, and the body of the loop will print the first element. So, for the first iteration the value of e will be 1. The block is executed, printing out 1. Since there are more elements in the list, execution continues, assigning 2 to the e. Again, the block is executed, but this time it prints out 2. Execution continues for the third iteration, which prints out 3. There are no more elements in the list, so the for loop is complete and execution continues with the next statement (in this case, there is no following statement, so execution finishes).
Quiz 3.13
Define a procedure, sum_list
, that takes as its input a list of numbers, and produces as its output the sum of all the elements in the input list. For example,
sum_list([1, 7, 4]) # -> 12
Answer
def sum_list(p):
result = 0
for e in p:
result = result + e
return result
print(sum_list([1, 4, 7])) # -> 12
Quiz 3.14
Define a procedure, measure_audacity
, that takes as its input a list of strings, and outputs a number that is a count of the number of elements in the input list that start with an uppercase letter 'A'
. For example,
measure_audacity(['Dawar', 'Salman', 'Kashif']) # -> 0
measure_audacity(['Anees', 'Ameena']) # -> 2
Answer
def measure_udacity(U):
count = 0
for e in U:
if e[0] == 'U':
count = count + 1
return count
Quiz 3.15
Define a procedure, find_element
, that takes as its input a list and a value of any type, and outputs the index of the first element in the input list that matches the value. If there is no matching element, output -1
. Examples:
find_element([1, 2, 3], 3) # -> 2
find_element(['alpha', 'bet a'], 'gamma') # -> -1
Answer
There are a many ways to answer this question. One way is to use a while loop:
def find_element(p,t):
i = 0
while i < len(p):
if p[i] == t:
return i
The risky thing about using while
loops instead of for
loops is that it is really easy to forget that you need to increase the index variable. If the loop is left at return i
it would run forever because the value of i
would never change. Make sure you remember increase the value of i
, and include the return
statement for when the while loop is finished, so that the code reads:
def find_element(p,t):
i = 0
while i < len(p):
if p[i] == t:
return i
i = i + 1
return -1
Another way to answer this question is to use a for loop. It may seem more intuitive to use a while loop rather than a for loop because the value you want to return from find_element
is the index itself. When you use a for loop you do not keep track of the index, you just go through each element in order. Here is how you would write a for loop:
def find_element(p, t):
i = 0
for e in p:
if e == t:
return i
i = i + 1
return -1
.index(...)
There are many other ways to define find_element
. A built-in list operation that we have not yet introduced that makes it easier to write find_element
is the index method:
<list>.index(<value>) # -> <position> or error
The index method is invoked on a list by passing in a value, and the output is the first position where that value sits in the list. If the list that does not contain any occurrences of the value you pass in, index produces an error (this is different from the find method for strings which we used in Unit 1, that returns a - 1 when the target string is not found). Examples:
p = [0, 1, 2]
print(p.index(2)) # 2
p = [0, 1, 2, 2, 2]
print(p.index(2)) # 2
Even though there are many 2 s in the list, the output is the first position where 2 occurs.
p = [0, 1, 2]
print(p.index(3)) # ValueError: list.index(x): x not in list
in
Since the requested behavior of find_element
is to output -1
when the input element is not found, we cannot use index directly to implement find_element since index produces an error when the element is not found. Instead, we can use another list operation, in
, to first test if the element is anywhere in the list. We have already seen in used in the for loop, however outside of a for loop header it means something different:
<value> in <list > # -> < Boolean>
The output is True
if the list contains an element matching value, and False
if it does not. Examples:
p = [0, 1, 2]
print(3 in p) # False
print(1 in p) # True
Similarly, you can use not in, which has the opposite meaning of in:
<value> not in <list>
If the value is not in the list the result of <value> not in <list>
is True
, and if the <value>
is in the <list>
than the result is False
. These two expressions are equivalent:
<value> not in <list>
not <value> in <list>
Quiz 3.16
Define find_element
, this time using .index()
.
Answer
Here is one way:
def find_element(p,t):
if t in p:
return p.index(t)
else:
return -1
Here is another way:
def find_element(p,t):
if t not in p:
return -1
return p.index(t)
Quiz 3.17
Define a procedure, union, that takes as inputs two lists. It should modify the first input list to be the set union of the two lists. Examples:
a = [1, 2, 3]
b = [2, 4, 6]
union(a, b)
print(a) # [1, 2, 3, 4, 6]
print(b) # [2, 4, 6]
Answer
def union(p, q):
for e in q:
if e not in p:
p.append(e)
.pop(...)
The pop operation mutates a list by removing its last element. It returns the value of the element that was removed.
<list>.pop() # -> element
Example:
a = [1, 2, 3]
b = a # both a and b refer to the same list
x = a.pop() # value of x is 3, and a and b now refer to the list [1, 2]
Quiz 3.18
Assume p
refers to a list with at least two elements. Which of these code fragments does not change the final value of p
.
-
A)
p.append(3) p.pop()
-
B)
x = p.pop() y = p.pop() p.append(x) p.append(y)
-
C)
x = p.pop() p.append(x)
-
D)
x = p.pop() y = p.pop() p.append(y) p.append(x)
Answer
All of the code fragments except for B), do not change the value of p
.
x = p.pop()
y = p.pop()
p.append(x)
p.append(y)