thinkpython第11章dictionaries
字典有点类似于列表,但是表现的更为一般。字典的索引(键)几乎可以是任意类型。
>>> eng2sp = dict()#dict()构建一个空字典 >>> print(eng2sp) {} >>> eng2sp['one'] = '1' >>> print(eng2sp) {'one': '1'}
>>> eng2sp = {'one':'1','two':'2','three':'3'} >>> print(eng2sp) {'one': '1', 'two': '2', 'three': '3'} >>> print(eng2sp) {'one': '1', 'two': '2', 'three': '3'} >>> print(eng2sp) {'one': '1', 'two': '2', 'three': '3'} >>> eng2sp = {'one':'1','two':'2','three':'3','zero':'0'} >>> print(eng2sp) {'one': '1', 'two': '2', 'three': '3', 'zero': '0'} >>> print(eng2sp) {'one': '1', 'two': '2', 'three': '3', 'zero': '0'} >>> #书上说字典项的顺序是随机的,但是在本机进行多次测试,均按照输入顺序进行输出
>>> #in运算符显示某个键是否在字典中作为关键字 >>> 'one' in eng2sp True >>> '1' in eng2sp False >>> #如果想查看某个值是否在字典中,可以使用方法values,返回包含关键字值的列表,然后使用in运算符 >>> vals = eng2sp.values() >>> '1' in vals True
11.1dictionary as a set of counters
>>> def histogram(s): d = dict() for i in s: if i not in d: d[i] = 1 else: d[i] += 1 return d >>> print(histogram('hellopython')) {'h': 2, 'e': 1, 'l': 2, 'o': 2, 'p': 1, 'y': 1, 't': 1, 'n': 1}
字典中的get函数,get('key',default value)。如果键在字典里,get返回对应的值;否则返回缺省值。所以我们可以把上述代码变成:
>>> def histogram(s): d = dict() for i in s: d[i] = d.get(i,0) + 1 return d >>> h = histogram('hellopython') >>> print(h) {'h': 2, 'e': 1, 'l': 2, 'o': 2, 'p': 1, 'y': 1, 't': 1, 'n': 1}
11.2looping and dictionaries
>>> def histogram(s): d = dict() for i in s: d[i] = d.get(i,0) + 1 return d >>> def print_hist(h): for c in h: print(c,h[c]) >>> h = histogram('python') >>> print(h) {'p': 1, 'y': 1, 't': 1, 'h': 1, 'o': 1, 'n': 1} >>> print_hist(h) p 1 y 1 t 1 h 1 o 1 n 1
11.3reverse lookup
下面是一个函数,接受一个值,返回第一个对应于该值的关键字:
>>> def reverse_lookup(d,v): for k in d: if d[k] == v: return k raise ValueError >>> d = {'one':'1','two':'2','three':'3'} >>> print(reverse_lookup(d,'1')) one >>> print(reverse_lookup(d,'4')) Traceback (most recent call last): File "<pyshell#21>", line 1, in <module> print(reverse_lookup(d,'4')) File "<pyshell#17>", line 5, in reverse_lookup raise ValueError ValueError
raise.语句引发了一个异常。当循环结束,v没有出现在字典关键字值里,所以此时引发一个ValueError异常。
raise语句接受一个详细的错误信息作为可选参数。
11.4dictionaries and lists
定义一个反转字典函数
>>> def invert_dict(d): inverse = dict() for key in d: val = d[key] if val not in inverse: inverse[val] = [key] else: inverse[val].append(key) return inverse >>> hist = histogram('parrot') >>> print(hist) {'p': 1, 'a': 1, 'r': 2, 'o': 1, 't': 1} >>> inverse = invert_dict(hist) >>> print(inverse) {1: ['p', 'a', 'o', 't'], 2: ['r']}
>>> #列表可以作为字典的关键字值,但是不能作为字典的关键字 >>> t = [1,2,3] >>> d = dict() >>> d[t] = 'apple' Traceback (most recent call last): File "<pyshell#39>", line 1, in <module> d[t] = 'apple' TypeError: unhashable type: 'list'
11.5memos
>>> known = {0:0,1:1} >>> def fibonacci(n): if n in known: return known[n] res = fibonacci(n-1) + fibonacci(n-2) known[n] = res return res >>> print(fibonacci(20)) 6765 >>> #known是一个字典,跟踪我们已经计算出的Fibonacci数字。起始项:0映射到0,1映射到1. >>> #无论何时调用Fibonacci,函数检查known字典。如果字典包含需要的结果,函数立即返回,否则计算新值,并把它加入字典,然后返回。
对比之前写过的Fibonacci函数,使用备忘录大大减少了运行时间
def fab(n): if n < 1: print('输入错误!') return -1 if n == 1 or n ==2: return 1 else: return fab(n-1) + fab(n-2)
11.6global variables
>>> old = True >>> def example(): old = False return old >>> print(example()) False >>> print(old) True >>> #example创建了一个新的局部变量old。局部变量随着函数的终结而销毁,而对全局变量没有影响 >>> #如果要在函数体里为全局变量重新赋值,必须在使用前声明全局变量 >>> new = True >>> def example2(): global new new = False return new >>> print(example2()) False >>> print(new) False
11,7long integers
python3.x没有长整型,在python2.x中才有long。
注:python3中支持int,float,bool,complex(复数)
11.8debugging
随着数据的增加,手动输出并检查数据变得越来越笨拙。我们可以:
缩小数据输入量
检查概要和类型
编写自我测试
pretty print the output:格式化的调试输出可以更容易发现错误。
11.10exercises