仅用作个人学习记录
Reference:https://inst.eecs.berkeley.edu/~cs61a
TreeⅠ
A tree() implementation
(20, [(12, [(9, [(7, []), (2, [])]), (3, [])]), (8, [(4, []), (4, [])])])
def tree(label, children=None):
""" Creates a tree whose root node is labeled LABEL and
optionally has CHILDREN, a list of trees."""
return (label, list(children or []))
def label(tree):
""" Returns the label of the root node of TREE. """
return tree[0]
def children(tree):
""" Returns a list of children of TREE. """
return tree[1]
t = tree(20, [tree(12,
[tree(9,
[tree(7), tree(2)]),
tree(3)]),
tree(8,
[tree(4), tree(4)])])
Tree creation: Doubling labels
利用一棵树创建另一棵树的函数通常也是递归的。
def double(t):
"""Returns a tree identical to T, but with all labels doubled."""
if is_leaf(t):
return tree(label(t) * 2)
else:
doubled_children = []
for c in children(t):
doubled_children += [double(c)]
return tree(label(t) * 2, doubled_children)
def double(t):
"""Returns the number of leaf nodes in T."""
return tree(label(t) * 2, [double(c) for c in children(t)])
Mutation
Non-destructive and Destructive
非破坏性操作:
>>> aThing
<output A>
>>> <operation on aThing (that obey abstraction boundaries)>
>>> aThing
<output A>
破坏性操作:
>>> aThing
<output A>
>>> <operation on aThing (that obey abstraction boundaries)>
>>> aThing
<output B>
非破坏性操作会创建一些新的数据,但不会改变原始输入数据,就像double(t)
,函数返回了一个新的树。
破坏性操作会改变原始输入数据。
Immutability and Mutability
不可变值创建后就不能再改变了。如int, float, string, tuple。
a_tuple = (1, 2)
a_tuple[0] = 3 # Error! Tuple items cannot be set.
a_string = "Hi y'all"
a_string[1] = "I" # Error! String elements cannot be set.
a_string += ", how you doing?" # How does this work?
an_int = 20
an_int += 2 # And this?
>>> a = (0,1)
>>> a[0] = 2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> str = 'hello'
>>> str[0] = a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment
>>> id(str)
1351376113008
>>> str += 'world'
>>> str
'helloworld'
>>> id(str)
1351376113264
>>> l = [23,24]
>>> id(l)
1351375719360
>>> l[1] = 99
>>> id(l)
1351375719360
>>> num = 1
>>> id(num)
140704539023008
>>> num += 1
>>> id(num)
140704539023040
可变值在整个计算过程中可以改变数值。所有指代同一对象的名称都受到突变的影响。如 list, dict。
grades = [90, 70, 85]
grades_copy = grades
grades[1] = 100
words = {"agua": "water"}
words["pavo"] = "turkey"
Mutation in function calls
函数可以更改其范围内任何对象的值。
def do_stuff_to(four):
four[0] = 10
four = [1, 2, 3, 4]
print(four[0])
do_stuff_to(four)
print(four[0])
Tree Ⅱ
TreeⅠ中实现的树是可变的吗?若不打破抽象极限,是不可变的。
A mutable tree()?
def set_label(tree, label):
"""Sets the label of TREE's root node to LABEL"""
def set_children(tree, children):
"""Sets the children of TREE to CHILDREN, a list of trees."""
tree[0] = label
tree[1] = childre
不可实现!不能改变元组的元素,因为元组是不可变的。
A mutable tree()
def tree(label, children=None):
return [label] + list(children or [])
def label(tree):
return tree[0]
def children(tree):
return tree[1:]
def set_label(tree, label):
tree[0] = label
def set_children(tree, children):
tree[1] = children
t = tree(20, [tree(12,
[tree(9,
[tree(7), tree(2)]),
tree(3)]),
tree(8,
[tree(4), tree(4)])])
set_label(t, 40)
set_children(t, [tree(24)])
A destructive tree doubling
def double(t):
"""Doubles every label in T, mutating T."""
set_label(t, label(t) * 2)
if not is_leaf(t):
for c in children(t):
double(c)
List
Nested list
matrix = [ [1,2,0,4], [0,1,3,-1], [0,0,1,8] ]
worst_list = [ [1, 2],
[],
[ [3, False, None],
[4, lambda: 5]]]
Copying lists
listA = [2, 3]
listB = listA
listC = listA[:]
listD = list(listA)
listA[0] = 4
listB[1] = 5