《Think Python 2e》学习精粹(十一):字典

《Think Python 2e》学习精粹(十一):字典



1、字典及映射

  • 字典:包含了一个索引的集合,被称为键(keys) ,和一个值(values)的集合, 一个键对应一个值,这种一一对应的关联被称为键值对(key-value pair) , 有时也被称为项(item)
  • 字典与列表类似,但是更加通用,在列表中,索引必须是整数,但在字典中,它们可以是(几乎)任何类型;
  • 在数学语言中,字典表示的是从键到值的 映射,所以也可以说每一个键 “映射到” 一个值;
  • dict函数生成一个不含任何项的新字典(空字典);
>>> eng2sp = dict()
>>> eng2sp
{}
  • 花括号 {} 表示一个空字典,你可以使用方括号向字典中增加项;
>>> eng2sp['one'] = 'uno'
>>> eng2sp
{'one': 'uno'}
  • 输出的格式同样也是输入的格式, 可以像这样创建一个包含三个项的字典:
>>> eng2sp = {'one': 'uno', 'two': 'dos', 'three': 'tres'}
  • 通常来说,字典中项的顺序是不可预知的,但这没有关系,因为字典的元素不使用整数索引来查找,而是用键来查找对应的值;
>>> eng2sp['two']
'dos'
  • 如果键不存在字典中,会抛出一个异常:
>>> eng2sp['four']
KeyError: 'four'
  • len函数也适用于字典,它返回键值对的个数;
  • in 操作符也适用于字典,它可以用来检验字典中是否存在某个键(仅仅有这个值还不够),并返回一个布尔值;
>>> 'one' in eng2sp
True
>>> 'uno' in eng2sp
False
  • 想要知道字典中是否存在某个值,可以使用 values 方法,它返回值的集合,然后你可以使用 in 操作符来验证;
>>> vals = eng2sp.values()
>>> 'uno' in vals
True

2、字典作为计数器集合

  • 实现:执行某种计算的方法;
  • 一个字符串,想计算每个字母出现的次数,使用字典的实现有一个优势,即不需要事先知道字符串中有几种字母, 只要在出现新字母时分配存储空间就好了,下面的函数 histogram 叫计数器集合或者直方图:
def histogram(s):
	d = dict()
	for c in s:
		if c not in d:
			d[c] = 1
		else:
			d[c] += 1
	return d
	
  • 字典有一个 get 方法,接受一个键和一个默认值作为参数, 如果字典中存在该键,则返回对应值,否则返回传入的默认值,用这个方法简化的 histogram 函数:
def histogram(s):
	d = dict()
	for c in s:
		d[c] = d.get(c, 0)+1
	return d
	

3、循环和字典

  • 在 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

4、逆向查找

  • 字典通过 v(alue) 找 k(ey) ,可能有不止一个的键其映射到值v, 并且没有简单的语法可以完成 逆向查找(reverse lookup),必须搜索;
def reverse_lookup(d, v):
	for k in d:
		if d[k] == v:
			return k
	raise LookupError()

  • raise 语句 能触发异常,这里它触发了 ValueError,这是一个表示查找操作失败的内建异常;
  • 逆向查找比正向查找慢得多,频繁执行这个操作或是字典很大,程序性能会变差;

5、字典和列表

  • 倒转字典函数:
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

h = {'p':1, 'a':1, 'r':2, 'o':1, 't':1}
d = invert_dict(h)

print(d)
PS C:\Users\Administrator> python D:\WorkSpace\thinkpython2e\new70.py
{1: ['p', 'a', 'o', 't'], 2: ['r']}
  • 列表可以作为字典中的值,但是不能是键,键必须是 可哈希的(hashable)
>>> t = [1, 2, 3]
>>> d = dict()
>>> d[t] = 'oops'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: list objects are unhashable
  • 字典与列表同为可变数据类型,与列表类似,即能作为字典值、但不能为键;

6、备忘录

  • 备忘录(memo):存储之前计算过的值以便今后使用的记录,字典便可以用作为备忘录;
  • 用字典作为备忘录的斐波那契函数:
known = {0:0, 1:1}

def fibonacci(n):
	if n in known:
		return known[n]

	return fibonacci(n-1) + fibonacci(n-2)

7、全局变量

  • __ main__ 中的变量可以被任何函数访问,它们也被称作 全局变量(global)
  • 与函数结束时就会消失的局部变量不同,不同函数调用时全局变量一直都存在;
  • 全局变量普遍用作 标记(flag), 也就是说明(标记)一个条件是否为真的布尔变量;
  • 要在函数内对全局变量重新赋值,必须在使用之前 声明(declare) 该全局变量;
been_called = False

def example2():
	global been_called
	been_called = True

example2()
print(been_called)
PS C:\Users\Administrator> python D:\WorkSpace\thinkpython2e\new82.py
True
  • global 语句 告诉编译器变量是全局变量、不生成新的变量;
  • 不可变类型全局变量在函数中引用前必须声明,可变类型(例如列表、字典)全局变量在函数中可以不加声明引用并修改、但不能重新赋值;
  • 全局变量有时是很有用的,但如果程序中有很多全局变量,而且修改频繁, 这样会增加程序调试的难度;

8、调试

  • 针对调试大数据集的一些建议:
    • 如果可能,减小数据集合的大小;
    • 检查摘要和类型;
    • 编写自检代码;
    • 格式化输出;
    • 搭建脚手架。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值