【Think Python】Python笔记(十一)字典
程序员文章站
2022-04-25 20:21:17
...
字典类型是Python的一种内建数据类型;
(一)字典即映射
- 字典实际上是与列表类似的,但是更加通用;
- 列表中,索引必须是整数;但是在字典中,可以几乎可以是任何类型;
- 字典包含一个索引的集合,称之为键(keys),还有一个**值(values)**的集合,一个键对应一个值,这种对应的关系称之为键值对,或者项;
-
dict
函数生成一个不含任何项的新的字典,它是一个内建函数名,所以自定义函数的时候需要避免 与之重名;
>>> eng2sp = dict()
>>> eng2sp
{}
- 花括号
{}
表示一个空的字典,可以使用方括号向其中增加项:
>>> eng2sp['one'] = 'uno'
>>> eng2sp
{'one', 'uno'}
- 通常来说,字典中的键值对的顺序是不可预知的,但是键值对的映射关系是确定的:
>>> eng2sp = {'one': 'uno', 'two': 'dos', 'three': 'tres'}
>>> eng2sp
{'one': 'uno', 'three': 'tres', 'two': 'dos'}
-
len()
函数也可以用于字典类型,求出字典中键值对的数量; -
in
操作符也适用于字典类型 ;可以用来检验字典中是不是存在某个键【不是值】
>>> 'one' in eng2sp
True
>>> 'uno' in eng2sp
False
- 想要知道字典中是不是存在某个值,可以使用
values
方法,这个方法返回值的集合,然后使用in
操作符进行验证:
>>> vals = eng2sp.values()
>>> 'uno' in vals
True
-
in
操作符对列表和字典采用不同的算法:- 对于列表,使用的是顺序查找;
- 对于字典,使用的是哈希表的算法;这样无论字典中含有多少项,
in
操作符搜索的时间是一样的;
(二)字典作为计数器集合
- 给定一个字符串,计算每个字母出现的次数:
def histogram(s):
d = dict()
for c in s:
if c in d:
d[c] += 1
else:
d[c] = 1
return d
>>> h = histogram('brontosaurus')
>>> h
{'a': 1, 'b': 1, 'o': 2, 'n': 1, 's': 2, 'r': 2, 'u': 2, 't': 1}
- 字典类有一个
get
方法,接受一个键和一个默认值作为参数:如果字典中存在该键,则返回对应值;否则返回传入的默认值
>>> h = histogram('a')
>>> h
{'a' : 1}
>>> h.get('a', 0)
1
>>> h.get('b', 0)
0
(三)循环和字典
在
for
循环中使用字典会遍历其所有的键:
def print_hist(h):
for c in h:
print(c, h[c])
>>> h = histogram('parrot')
>>> print_hist(h)
a 1
p 1
r 2
t 1
o 1
- 字典中的键是无序的,如果想要按照顺序遍历字典,使用内建方法
sorted
>>> for key in sorted(h)
... print(key, h[key])
a 1
o 1
p 1
r 2
t 1
(四)逆向查找
- 给定一个字典
d
和一个键t
,很容易找到相对应的值v = d[t]
,这个过程称之为查找;- 但是如果想通过值
v
,查找相对应的键key
;这个过程是比较麻烦的,因为:第一,可能有多于一个的键对应同样的值;第二,没有简单的语法可以完成这个过程,必须进行搜索;
- 下面的函数接受一个值,并返回映射到这个值的第一个键:
def reverse_lookup(d, v):
for k in d:
if d[k] == v:
return k
raise LookupError
-
这里
raise
语句可以触发异常,这里是触发了LookupError
,这是一个表示查找操作失败的内建异常;- 成功的逆向查找的例子:
>>> h = histogram('parrot') >>> key = reverse_lookup(h, 2) >>> key 'r'
- 失败的例子:
>>> key = reverse_lookup(h, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 5, in reverse_lookup LookupError
-
raise
语句接受一个详细的错误信息作为可选的参数:
raise LookupError('value does not appear in the dictionary')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
LookupError: value does not appear in the dictionary
(五)字典和列表
在字典中,列表可以作为值出现;
- 下面的函数实现倒转字典:
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)
- 例子:
>>> hist = histogram('parrot')
>>> hist
{'a': 1, 'p': 1, 'r': 2, 't': 1, 'o': 1}
>>> inverse = invert_dict(hist)
>>> inverse
{1: ['a', 'p', 't', 'o'], 2: ['r']}
-
列表可以作为字典的值,但是不能作为键;因为字典使用哈希表实现,这意味着键必须是可哈希的(hashable)
-
类似的,一些可变类型都不可以作为字典的键;不能使用数组作为键,但是可以使用元组;
(六)备忘录
- 在
fibonacci
函数中,输入的参数越大,函数运行的时间越长,而且时间增长的非常快,原因如下:
可以看出,当n=1和n=0被重复调用的很多次,而且随着参数的不断变大,这种冗余会越来越大;
- 一个解决的办法是将已经计算的值保存在字典中,这个称之为备忘录(memo),如下:
known = {0:0, 1:1}
def fibinacci(n):
if n in known:
return known[n]
res = fibonacci[n-1] + fibonacci[n-2]
known[n] = res
return res
(七)全局变量
- 上面的例子中,
known
是在函数的外部创建的,所以它属于被称之为__main__
的特殊帧;__main__
中的变量可以被任何函数进行访问,所以称之为全局变量(global);- 函数中的变量会随着函数的结束而消失,但是全局变量在不同函数调用时一直存在;
- 全局变量经常用作标记(flag),也就是说明(标记)一个条件是否为真的布尔变量
- 在函数内部对全局变量重新赋值,必须声明这个 是全局变量:
been_called = False
def example():
global been_called
been_called = True
- 如果全局变量是可变的,可以不加声明地修改:
known = {0:0, 1:1}
def example():
know[2] = 1
- 但是,如果想要对变量重新进行赋值,必须声明:
def example():
global known
known = doct()
全局变量有时是很有用的,但如果你的程序中有很多全局变量,而且修改频繁, 这样会增加程序调试的难度。
(八)调试
当使用较大的数据集的时候,通过打印并手工检查数据进行调试是很不方便的
-
针对这个问题的建议:
-
缩小输入:如果有可能,减小数据集合的大小;如果出错了,你可以将 n 缩小为会导致该错误的最小值,然后在查找和解决错误的同时,逐步增加 n 的值。
-
检查摘要和类型:考虑打印数据的摘要,而不是打印并检查全部的数据集合;运行时错误一个常见原因是数据类型不正确
-
编写自检代码:有时候可以写代码自动检查错误:
- 例如,如果你正在计算数字列表的平均数,你可以检查其结果是不是大于列表中最大的元素,或者小于最小的元素。 这被称 作“合理性检查”,因为它能检测出“不合理的”结果。
- 另一类检查是比较两个不同计算的结果,来看一下它们是否一致。这被称作“一致性检查”。
-
格式化输出:在第六节的调试中;还有一个是
pprint
,它可以用一种更加人类可读的方式战术内建类型 -
在编程的时候,搭建一些脚手架代码,可以有效减少调试的时间;
-
上一篇: 20. 有效的括号
下一篇: Think In Java 读书笔记
推荐阅读
-
在Python中操作字典之clear()方法的使用
-
Python—Numpy学习笔记(二)array的用法
-
机器学习笔记--Python之Numpy
-
Python ORM框架SQLAlchemy学习笔记之数据查询实例
-
机器学习笔记(一):python 模块 numpy
-
python网络编程学习笔记(七):HTML和XHTML解析(HTMLParser、BeautifulSoup)
-
Python ORM框架SQLAlchemy学习笔记之映射类使用实例和Session会话介绍
-
Python ORM框架SQLAlchemy学习笔记之关系映射实例
-
python网络编程学习笔记(九):数据库客户端 DB-API
-
Python把csv数据写入list和字典类型的变量脚本方法