3. 最好不用“获取许可”,也无需“要求原谅”这个小标题可能会稍微让人有点懵,让我来简短的解释一下:“获取许可”与“要求原谅”是两种不同的编程风格 。如果用一个经典的需求:“计算列表内各个元素出现的次数” 来作为例子,两种不同风格的代码会是这样:
-
# AF: Ask for Forgiveness
-
# 要做就做,如果抛出异常了,再处理异常
-
def counter_af(l):
-
result = {}
-
for key in l:
-
try:
-
result[key] += 1
-
except KeyError:
-
result[key] = 1
-
return result
-
# AP: Ask for Permission
-
# 做之前,先问问能不能做,可以做再做
-
def counter_ap(l):
-
result = {}
-
for key in l:
-
if key in result:
-
result[key] += 1
-
else:
-
result[key] = 1
-
return result
不过,示例里的两段代码在现实世界中都非常少见 。为什么?因为如果你想统计次数的话,直接用
collections.defaultdict
就可以了:-
from collections import defaultdict
-
def counter_by_collections(l):
-
result = defaultdict(int)
-
for key in l:
-
result[key] += 1
-
return result
- 操作字典成员时:使用
collections.defaultdict
类型
- 或者使用
dict[key]=dict.setdefault(key,0)+1
内建函数
- 或者使用
- 如果移除字典成员,不关心是否存在:
- 调用 pop 函数时设置默认值,比如
dict.pop(key,None)
- 调用 pop 函数时设置默认值,比如
- 在字典获取成员时指定默认值:
dict.get(key,default_value)
- 对列表进行不存在的切片访问不会抛出
IndexError
异常:["foo"][100:200]
4. 使用 next 函数
next
是一个非常实用的内建函数,它接收一个迭代器作为参数,然后返回该迭代器的下一个元素 。使用它配合生成器表达式,可以高效的实现“从列表中查找第一个满足条件的成员”之类的需求 。-
numbers = [3, 7, 8, 2, 21]
-
# 获取并 **立即返回** 列表里的第一个偶数
-
print(next(i for i in numbers if i % 2 == 0))
-
# OUTPUT: 8
5. 使用有序字典来去重字典和集合的结构特点保证了它们的成员不会重复,所以它们经常被用来去重 。但是,使用它们俩去重后的结果会丢失原有列表的顺序 。这是由底层数据结构“哈希表(Hash Table)”的特点决定的 。
-
>>> l = [10, 2, 3, 21, 10, 3]
-
# 去重但是丢失了顺序
-
>>> set(l)
-
{3, 10, 2, 21}
collections.OrderedDict
模块:-
>>> from collections import OrderedDict
-
>>> list(OrderedDict.fromkeys(l).keys)
-
[10, 2, 3, 21]
Hint: 在 Python 3.6 中,默认的字典类型修改了实现方式,已经变成有序的了 。并且在 Python 3.7 中,该功能已经从 语言的实现细节变成了为可依赖的正式语言特性 。
但是我觉得让整个 Python 社区习惯这一点还需要一些时间,毕竟目前“字典是无序的”还是被印在无数本 Python 书上 。所以,我仍然建议在一切需要有序字典的地方使用 OrderedDict 。
推荐阅读
- MySQL的查询性能分析神器:explain命令的使用详解
- Python爬虫:scrapy之Cookie和Session
- Python中的高阶函数
- 国内顶尖大佬整理的Python入门教程完整版!懂中文就能学会
- 一文看懂Python变量和赋值语句
- 在Python中定义Main函数
- 红衣天使怎么养 小红衣怎么养
- 怎样正确使用阿司匹林
- 买房为什么要交公共维修基金?什么情况下使用公共维修基金……
- 医保卡使用有技巧,做对这几件事报销的更多