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

原文地址:https://www.cnblogs.com/Kingwjk/p/7909286.html