原文: Python: The Dictionary Playbook
译者: youngsterxyf
我经常碰到关于Python中字典的各种样板代码,因此我决定在此展示一些,并分享完成相同操作的更加简洁的方式。
上演: 字典剧本
1. “你在吗?”
这个相当简单,但不可错过 - 找出某个键(key)是否存在于字典中。
蹩脚的版本
dct.has_key(key)
Pythonic的方式
key in dct
2. “尤达测试”(译注:尤达的意思见yoda)
对于那些掌握了“你在吗”剧本的程序员来说,这通常是另一个简单但是令人讨厌的事情。它不仅仅可用于字典数据类型,但非常普通。
干这事,你必须不能这样
not key in dct
英语,你会说吗?
key not in dct
3. “无论如何也要得到其值”
这个非常流行。你有一个字典和一个键,然后想修改这个键对应的值。例如,将该值加1(比方说你正在计算某些东西)。
样板
if key not in dct:
dct[key] = 0
dct[key] = dct[ket] + 1
巧妙的方式
dct[key] = dct.get(key, 0) + 1
如果存在该键, dct.get(key[, default])
返回 dct[key]
,否则返回 default
。
更棒的方式
如果你使用Python 2.7,并且想统计元素的数目,可以使用Counter。
>>> from collections import Counter
>>> d = [1, 1, 1, 2, 2, 3, 1, 1]
>>> Counter(d)
Counter({1: 5, 2: 2, 3: 1})
这里有个更完整的例子:
>>> counter = Counter()
... for _ in range(10):
... num = int(raw_input("Enter a number: "))
... counter.update([num])
...
... for key, value in counter.iteritems():
... print "You have entered {}, {} times!".format(key, value)
Enter a number: 1
Enter a number: 1
Enter a number: 2
Enter a number: 3
Enter a number: 51
Enter a number: 1
Enter a number: 1
Enter a number: 1
Enter a number: 2
Enter a number: 3
You have entered 1, 5 times!
You have entered 2, 2 times!
You have entered 3, 2 times!
You have entered 51, 1 times!
4. “创造可能”(译注:这里"make it happen"还不知道该如何翻译)
有时你的字典中包含可变对象,你想初始化并修改它们。比方你要把一些数据整理存入一个字典,其值是列表(示例来自Stack Overflow上的这个解答)
详细说明
dct = {}
for (key, value) in data:
if key in dct:
dct[key].append(value)
else:
dct[key] = [value]
以pythonic方式实现
dct = {}
for (key, value) in data:
group = dct.setdefault(key, []) #key可能已经存在
group.append(value)
如果键存在, setdefault(key, [])
返回 dct[key]
,否则将键对应的值设置为 default
并返回。与 get
相比,当缺省值是一个你可以修改的对象时,这种方式使你不需要将修改后的值再次插入字典中。
Rocking it out (译注:真心不知道这句该如何翻译)
dct = defaultdict(list)
for (key, value) in data:
dct[key].append(value) # 所有键都有一个缺省值
defaultdict
非常赞!不言自明 —— 带有缺省值的字典。这意味这每次访问 dct
中的某个键,如果不存在(通常会抛出一个 KeyError
异常),则以缺省值作为其值创建该键。这就好似使用 setdefault
来完成每次访问。
我发现 defaultdict
的一个有趣用法是实现稀疏数据结构。设置好 defaultdict 的缺省值,以坐标(或者任何合适的东西)作为其键。我曾这样去表示多维网格,肯定比使用复杂的列表嵌套简单得多。
更有意思的一个使用示例见一行代码定义树