defcountdown(k):if k>0:yield kyield from countdown(k-1)''' 等价于 for i in countdown(k-1): yield i '''else:yield'Blast off'if__name__=="__main__": t = countdown(3)for i in t:print(i)
3
2
1
Blast of
1 2 3 4 5 6 7 8 9 10 11
defprefixes(s):if s:yield from prefixes(s[:-1])yield sdefsubstrings(s):if s:yield from prefixes(s)yield from substrings(s[1:])if__name__=="__main__":print(list(prefixes("both")))print(list(substrings("top")))
defpartitions(n,m):if n<0or m==0:return []else: exact_match = []if n==m: exact_match = [str(m)] with_m = [p+'+'+str(m) for p in partitions(n-m,m)] without_m = partitions(n,m-1)return exact_match+with_m+without_mif__name__=="__main__":for p in partitions(6,4):print(p)
defpartitions(n,m):if n>0and m>0:if n==m:yieldstr(m)for p in partitions(n-m,m):yield p+'+'+str(m)yield from partitions(n,m-1)if__name__=="__main__": t = partitions(6,4)for p inrange(5):print(next(t))
deftree(label, branches=[]):for branch in branches:assert is_tree(branch), "branches must be trees"# 确保构造的是一棵树return [label] +list(branches) # 将同一层的分支节点放在一个列表中deflabel(tree):return tree[0]defbranches(tree):return tree[1:]defis_tree(tree):"""判断是不是一棵树"""iftype(tree) !=listorlen(tree) <1: # 确保树的分支是树,以及存在一个值returnFalsefor branch in branches(tree): # 确保树的分支的分支都是树ifnot is_tree(branch):returnFalsereturnTruedefis_leaf(tree): """判断树本身是不是叶子节点"""returnnot branches(tree)if__name__=="__main__": t = tree(1, [tree(5, [tree(7)]), tree(6)])print(t)print(label(t))print(branches(t))print(label(branches(t)[0]))
[1, [5, [7]], [6]]
1
[[5, [7]], [6]]
5
Tree Processing
处理叶子节点
使用递归,将会在每个分支节点进行递归调用,最后合并
1 2 3 4 5 6 7 8 9 10
defcount_leaves(t):"""Count the leaves of tree T"""if is_leaf(t):return1else:returnsum([count_leaves(b) for b in branches(t)])if__name__=="__main__": t = tree(1, [tree(5, [tree(7)]), tree(6)])print(count_leaves(t))
2
返回叶子节点的值
实现leaves函数,返回树的叶子节点的值的列表
1 2 3 4 5 6 7 8 9 10
defleaves(tree):"""return a list containing the leaf labels of tree"""if is_leaf(tree):return [label(tree)]else:returnsum([leaves(b) for b in branches(tree)], [])if__name__=="__main__": t = tree(1, [tree(5, [tree(7)]), tree(6)])print(leaves(t))
[7, 6]
根据树创建树
使用递归根据另一棵树创建一颗新树 如让叶子节点值+1的树
或让所有节点都+1的树
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
defincrement_leaves(t):"""return a tree like t but with leaf labels incremented"""if is_leaf(t):return tree(label(t)+1)else: bs = [increment_leaves(b) for b in branches(t)]return tree(label(t), bs)defincrement(t):"""return a tree like t but with all labels incremented"""return tree(label(t)+1, [increment(b) for b in branches(t)])if__name__=="__main__": t = tree(1, [tree(5, [tree(7)]), tree(6)])print(leaves(t))print(increment_leaves(t))print(increment(t))
[7, 6]
[1, [5, [8]], [7]]
[2, [6, [8]], [7]]
例:print_tree
按节点在树中的深度缩进打印一颗树
1 2 3 4 5 6 7 8
defprint_tree(t, indent =0):print(' '*indent +str(label(t)))for b in branches(t): print_tree(b, indent+1)if__name__=="__main__": t = tree(1, [tree(5, [tree(7)]), tree(6)])print(print_tree(t))
1
5
7
6
None
例:
求从根节点沿路径到叶子节点求和并打印
1 2 3 4 5 6 7 8 9 10 11
defprint_sums(t, so_far): so_far = so_far +label(t)if is_leaf(t):print(so_far)else:for b in branches(t): print_sums(b,so_far)if__name__=="__main__": t = tree(1, [tree(5, [tree(7)]), tree(6)])print(print_sums(t, 0))
defdivide(quotients, divisors):"""Return a dictonary in which each quotient q is a key for the list of divisors that it divides evenly.>>> divide([3, 4, 5], [8, 9, 10, 11, 12]) {3: [9, 12], 4: [8, 12], 5: [10]}>>> divide(range(1, 5), range(20, 25)) {1: [20, 21, 22, 23, 24], 2: [20, 22, 24], 3: [21, 24], 4: [20, 24]} """return {i: [x for x in divisors if x%i==0] for i in quotients}
defcloser_city(lat, lon, city_a, city_b):""" Returns the name of either city_a or city_b, whichever is closest to coordinate (lat, lon). If the two cities are the same distance away from the coordinate, consider city_b to be the closer city.>>> berkeley = make_city('Berkeley', 37.87, 112.26)>>> stanford = make_city('Stanford', 34.05, 118.25)>>> closer_city(38.33, 121.44, berkeley, stanford) 'Stanford'>>> bucharest = make_city('Bucharest', 44.43, 26.10)>>> vienna = make_city('Vienna', 48.20, 16.37)>>> closer_city(41.29, 174.78, bucharest, vienna) 'Bucharest' """ fake_city = make_city('fake', lat, lon)if distance(fake_city,city_a)<distance(fake_city,city_b):return get_name(city_a)else:return get_name(city_b)
from fractions import gcddefrational(n,d): g = gcd(n,d)return [n//g, d//g]
Data Representation
数据抽象的基本思想:通过它的行为来识别该抽象数据类型
改变有理数的表现形式
1 2 3 4 5 6 7 8 9 10 11 12 13 14
defrational(n,d):defselect(name):if name =='n':return nelif name =='d':return dreturn selectdefnumer(x):"""Return the numerator of rational number x"""return x('n')defdenom(x):"""Return the denominator of rational number x"""return x('d')