Home CS61A: Lecture 14
Post
Cancel

CS61A: Lecture 14

Mutability

  • In the way that names refer to values, we can have multiple names refer to the same values
    • The names declared within functions may also refer to values outside of the scope of the function
1
2
3
4
5
6
7
8
9
10
11
s = [3, 3, 7, 9]
u = s
print("original s:", s)
s[1] = 5
s.append(11)
print("New length of s: ", len(s))
print("What is u?", u)
def f(r):
    r.append(13)
f(s)
print("What is u now?", u)
1
2
3
4
original s: [3, 3, 7, 9]
New length of s:  5
What is u? [3, 5, 7, 9, 11]
What is u now? [3, 5, 7, 9, 11, 13]
  • The reason that u is updated even after the function call is because s is passed into the function. Thus, both r and u point to the same list that s is pointing to.
  • Mutable values include lists. Integers and strings are immutable values.
    • Strings are not lists. They have similar properties, but ultimately still different.
1
2
3
word = "wonderful"
words = ["wonderful", "world"]
" ".join(words)
1
'wonderful world'
  • The type system in python means that one name could refer to a value, but that reference may be changed later on.

Building a new list

  • We may do so with list comprehension, but we may also use a for-loop, and there is a difference
1
2
3
4
5
6
7
8
9
10
11
12
13
s = [3, 5, 7, 9, 11, 13]
u = s
print("Current s:", s)
print("Current u:", u)
t = [x+3 for x in s] # This creates a new list
v = s[:]
print("-"*40)
for i in range(len(s)): # This modifies the original list
    s[i] = s[i] + 3
print("current t:", t)
print("Current s:", s)
print("current u:", u)
print("current v:", v)
1
2
3
4
5
6
7
Current s: [3, 5, 7, 9, 11, 13]
Current u: [3, 5, 7, 9, 11, 13]
----------------------------------------
current t: [6, 8, 10, 12, 14, 16]
Current s: [6, 8, 10, 12, 14, 16]
current u: [6, 8, 10, 12, 14, 16]
current v: [3, 5, 7, 9, 11, 13]
  • We may create a new list with the following strategies
    • Assign the name to a slice of a list
    • Apply the list() constructor
    • Use list comprehension
    • Literally creating a new list.
  • Whenever we create a new list, that name is bound to a new value that is separate from the original list from which the copy was created.
1
2
3
4
5
6
7
8
9
10
11
12
def sums(n, m):
    """Review this problem, why use min(m+1, n)????"""
    result = []
    for k in range(1, min(m+1, n)):
        for rest in sums(n-k, m):
            if rest[0] != k:
                result.append([k] + rest)
    if n<=m:
        result.append([n])
    return result

sums(5,5)
1
[[1, 3, 1], [1, 4], [2, 1, 2], [2, 3], [3, 2], [4, 1], [5]]
  • A list describes a path if it contains labels along a path from the root of a tree. Implement make_path, which takes a tree t with unique labels and a list p that starts with the root label of t. It returns the tree u with the fewest nodes that contains all the paths in t as well as (possibly new) path p.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from tree import *
def make_path(t1, p):
    assert p[0] == label(t), 'Impossible'
    if len(p) == 1:
        return t
    new_branches = []
    found_p1 = False
    for b in branches(t):
        if label(b) == p[1]:
            new_branches.append(make_path(b, p[1:]))
            found_p1 = True
        else:
            new_branches.append(b)
    if not found_p1:
        new_branches.append(make_path(tree(p[1]),p[1:]))
    return tree(label(t), new_branches)

Sameness and Change

  • As long as we never modify objects, a compound object is just the totality of its pieces.

Identity Operators

  • Identity:
    • <exp0> is <exp1>
    • Evaluates to True if both <exp0> and <exp1> evaluate to the same object
  • Equality
    • <exp0> == <exp1>
    • Evaluates to True if both <exp0> and <exp1> evaluates to the same value.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def make_path(t1, p):
    assert label(t1) == p[0], "Impossible"
    found_p1 = False
    new_branches_to_add = []
    if (len(p) == 1):
        return t1
    for branch in branches(t1):
        if label(branch) == p[1]:
            found_p1 = True
            new_branches_to_add.append(make_path(branch, p[1:]))
        else:
            new_branches_to_add.append(branch)
    if not found_p1:
        new_branches_to_add.append(make_path(tree(p[1]), p[1:]))
    return tree(p[0], new_branches_to_add)
This post is licensed under CC BY 4.0 by the author.

CS61A: Trees

CS61A: Mutability