忘记从哪得知《Python进阶》这本书了,前几天花了几个小时读完之后,学到了很多以前不知道或是不了解的关于Python的种种,先挑几条比较实用的记录一下,以后再详细探讨。

1. open函数

很多人(也包括我)经常是这样使用open函数的:

f = open('data.txt', 'r')
data = f.read()
f.close()

但是,这种使用方式有一个隐患:open的返回值是操作系统分配的一个文件句柄,处理完文件需要归还这个文件句柄,避免超出一次能打开的文件句柄数上限。在如上代码中,如果有任意异常正好在f = open(…)之后产生,f.close()将不会被调用(文件句柄被归还与否,取决于Python解释器的实现),为了确保无论是否产生异常文件都能被关闭,可以使用Python中的with语句:

with open('data.txt', 'r') as f:
data = f.read()

2. defaultdict容器

与dict类型不同的是,你不需要检查defaultdict中的key是否存在,所以可以这样做:

from collections import defaultdict
colours = (
('Bob', 'White'),
('Alice', 'Blue'),
('Andy', 'Green'),
('Bob', 'Black'),
('Andy', 'Red'),
)
result = defaultdict(list)
for name, colour in colours:
result[name].append(colour)

另外当你在一个字典中对一个键进行嵌套赋值时,如果这个键不存在会触发keyError异常:

some_dict = {}
some_dict['Andy']['gender'] = 'Man' # KeyError: 'colours'

defaultdict允许我们用一个聪明的方式绕过这个问题:

from collections import defaultdict
tree = lambda: defaultdict(tree)
some_dict = tree()
some_dict['Andy']['gender'] = 'Man'

Python中还有counter、deque、namedtuple等容器,但是貌似并不常用,就不说了。

3. 列表并行排序

假设现在获得了四个用户两个不同属性的数据列表y1和y2,现在需要按照y1中数据排序绘制曲线。最近,在做实验的过程中频繁遇到这种需求,使用这个技巧能很方面地满足需求:

y1 = [2, 1, 10, -3]
y2 = [1, 4, 9, 13]
data = zip(y1, y2)
data.sort()
y1, y2 = map(lambda t: list(t), zip(*data))
# y1 = [-3, 1, 2, 10], y2 = [13, 4, 1, 9]