Lecture 23
Mutable Data�
reminder/Announcement
Mutability
Mutability
Mutability
Observation:Demo
Mutation Can Happen Within a Function Call
A function can change the value of any object in its scope.
>>> four = [1, 2, 3, 4]
Mutation Can Happen Within a Function Call
A function can change the value of any object in its scope
>>> four = [1, 2, 3, 4]
>>> len(four)
4
Mutation Can Happen Within a Function Call
A function can change the value of any object in its scope
>>> four = [1, 2, 3, 4]
>>> len(four)
4
>>> mystery(four)
Mutation Can Happen Within a Function Call
A function can change the value of any object in its scope
>>> four = [1, 2, 3, 4]
>>> len(four)
4
>>> mystery(four)
>>> len(four)
2
Mutation Can Happen Within a Function Call
A function can change the value of any object in its scope
>>> four = [1, 2, 3, 4]
>>> len(four)
4
>>> mystery(four)
>>> len(four)
2
def mystery(s):
s.pop()
s.pop()
Mutation Can Happen Within a Function Call. demo
A function can change the value of any object in its scope
>>> four = [1, 2, 3, 4]
>>> len(four)
4
>>> mystery(four)
>>> len(four)
2
def mystery(s):
s.pop()
s.pop()
def mystery(s):
s[2:] = []
Mutation Can Happen Within a Function Call. demo
A function can change the value of any object in its scope
>>> four = [1, 2, 3, 4]
>>> len(four)
4
>>> another_mystery() # no arguments
>>> len(four)
2
def mystery(s):
s.pop()
s.pop()
Mutation Can Happen Within a Function Call. demo
A function can change the value of any object in its scope
>>> four = [1, 2, 3, 4]
>>> len(four)
4
>>> another_mystery() # no arguments
>>> len(four)
2
def mystery(s):
s.pop()
s.pop()
def another_mystery():
four.pop()
four.pop()
How about tuples?
>>> four = (1, 2, 3, 4)
>>> len(four)
4
>>> mystery(four)
>>> four
What is four?
A: (1, 2, 3, 4)
B: (1, 2)
C: ( )
D: Something else
def mystery(s):
s[2:] = ( )
From value to storage …
Explanation (board)
From value to storage …
2
x = [1, 2, 3]
y = 6
x [1] = y
x [1]
From value to storage …
Parameter passing: Output?
def test(x):
x = x + 1
y = 10
test(y)
print(y)
A: 10
B: 11
C: None
D: Error
E: I do not know
Parameter passing: Output?
def test(x):
x[0] = x[0] + 1
y = [1, 2, 3]
test(y)
print(y)
A: [1, 2, 3]
B: [2, 2, 3]
C: None
D: Error
E: I do not know
What is the output?
var = ([1, 2], [3, 4])
copy = var
var[0][1] = "changed"
var = ([1, "changed"], [3, 4])
print(copy is var)
A : Error
B: None
C: ([1, “changed”], [3, 4])
D: True
E: False
What is the output?
def func(lst):
new_list = lst
new_list[0] = ‘m’
param = “string”
func(param)
print(param)
A : Error
B: None
C: string
D: mtring
E: None of the above
mic
What is the output?
def func(lst):
new_list = lst
new_list[0] = 'changed'
param = [1, 2, 3, 4, 5]
func(param)
print(param)
A : Error
B: None
C: [1, 2, 3, 4, 5]
D: [“changed”, 2, 3, 4, 5]
E: None of the above
Examples
x = [1, 2 , 3]
y = x
print (y)
x[1] = 11
print (y)
x = [1, 2]
y = [x, x, x]
print (y)
x[1] = 3
print (y)
y[2] = [1, 3]
print (y[0] == y[2])
print (y[0] is y[2])
x = [1, 2 , 3]
y = x
print (y)
x[1] = 11
print (y)
x = [1, 2]
y = [x, x, x]
print (y)
x[1] = 3
print (y)
y[2] = [1, 3]
print (y[0] == y[2])
print (y[0] is y[2])
Copies, ‘is’ and ‘==‘
>>> alist = [1, 2, 3, 4]
>>> alist == [1, 2, 3, 4] # Equal values?
True
>>> alist is [1, 2, 3, 4] # same object?
False
>>> blist = alist # assignment refers
>>> alist is blist # to same object. Shallow copy
True
>>> blist = list(alist) # type constructors copy
>>> blist is alist
False
Copies, ‘is’ and ‘==‘
>>> alist = [1, 2, 3, 4]
>>> alist == [1, 2, 3, 4] # Equal values?
True
False
>>> blist = alist[ : ] #integers
>>> blist is alist
>>> blist
[1, 2, 3, 4]
Copies, ‘is’ and ‘==‘
>>> alist = [[1], [2], [3], [4]]
>>> blist = alist[:]
>>> blist[0][0] = 10
>>> alist is blist
False
But try to print these lists.
Real deep copy
import copy
list_a = [[1, 2], [3, 4], [5, 6]]
list_b = copy.deepcopy(list_a)
# Modify an element in the copied list
list_b[0][0] = 10
print(list_a) # Output: [[1, 2], [3, 4], [5, 6]]
print(list_b) # Output: [[10, 2], [3, 4], [5, 6]]
Identity Operators: is is not
Identity Operators
Identity Operators
Identical objects are always equal values
In-place algorithm
In-place algorithm
def to_odd(lst):
output = []
for i in lst:
if i%2==0:
output.append(i+1)
else:
output.append(i)
return output
Not in place!��Another list of the O(n) space is used.
In-place algorithm
def to_odd(lst):
for i in range(len(lst)):
if lst[i]%2==0:
lst[i] = lst[i] + 1
In place!��No other space besides a given list was used.
def to_odd(lst):
output = []
for i in lst:
if i%2==0:
output.append(i+1)
else:
output.append(i)
return output
>>> lst = [1,2,3]
>>> to_odd(lst)
>>> print(lst)
[1, 2, 3] #values are NOT changed
def to_odd(lst):
for i in range(len(lst)):
if lst[i]%2==0:
lst[i] = lst[i] + 1
>>> lst = [1,2,3]
>>> to_odd(lst)
>>> print(lst)
[1, 3, 3] #values are changed
Mutable Default Arguments are Dangerous
Mutable Default Arguments are Dangerous
What will happen if I call f()again?
A: 1
B: 2
C: 3
D: 0
E: Error