1.6 å—å…¸ä¸çš„é”®æ˜ å°„å¤šä¸ªå€¼Â¶
问题¶
æ€Žæ ·å®žçŽ°ä¸€ä¸ªé”®å¯¹åº”å¤šä¸ªå€¼çš„å—典(也å�« multidict)?
解决方案¶
一个å—典就是一个键对应一个å�•å€¼çš„æ˜ å°„ã€‚å¦‚æžœä½ æƒ³è¦�ä¸€ä¸ªé”®æ˜ å°„å¤šä¸ªå€¼ï¼Œé‚£ä¹ˆä½ å°±éœ€è¦�将这多个值放到å�¦å¤–的容器ä¸ï¼Œ 比如列表或者集å�ˆé‡Œé�¢ã€‚æ¯”å¦‚ï¼Œä½ å�¯ä»¥åƒ�下é�¢è¿™æ ·æž„é€ è¿™æ ·çš„å—典:
d = {
'a' : [1, 2, 3],
'b' : [4, 5]
}
e = {
'a' : {1, 2, 3},
'b' : {4, 5}
}
选择使用列表还是集å�ˆå�–å†³äºŽä½ çš„å®žé™…éœ€æ±‚ã€‚å¦‚æžœä½ æƒ³ä¿�æŒ�å…ƒç´ çš„æ�’入顺åº�就应该使用列表, 如果想去掉é‡�å¤�å…ƒç´ å°±ä½¿ç”¨é›†å�ˆï¼ˆå¹¶ä¸”ä¸�å…³å¿ƒå…ƒç´ çš„é¡ºåº�问题)。
ä½ å�¯ä»¥å¾ˆæ–¹ä¾¿çš„使用 collections 模å�—ä¸çš„ defaultdict æ�¥æž„é€ è¿™æ ·çš„å—典。
defaultdict 的一个特å¾�是它会自动åˆ�始化æ¯�个 key åˆšå¼€å§‹å¯¹åº”çš„å€¼ï¼Œæ‰€ä»¥ä½ å�ªéœ€è¦�å…³æ³¨æ·»åŠ å…ƒç´ æ“�作了。比如:
from collections import defaultdict
d = defaultdict(list)
d['a'].append(1)
d['a'].append(2)
d['b'].append(4)
d = defaultdict(set)
d['a'].add(1)
d['a'].add(2)
d['b'].add(4)
需è¦�注æ„�的是, defaultdict 会自动为将è¦�访问的键(就算目å‰�å—å…¸ä¸å¹¶ä¸�å˜åœ¨è¿™æ ·çš„é”®ï¼‰åˆ›å»ºæ˜ å°„å®žä½“ã€‚
å¦‚æžœä½ å¹¶ä¸�需è¦�è¿™æ ·çš„ç‰¹æ€§ï¼Œä½ å�¯ä»¥åœ¨ä¸€ä¸ªæ™®é€šçš„å—典上使用 setdefault() 方法æ�¥ä»£æ›¿ã€‚比如:
d = {} # 一个普通的å—å…¸
d.setdefault('a', []).append(1)
d.setdefault('a', []).append(2)
d.setdefault('b', []).append(4)
但是很多程åº�员觉得 setdefault() 用起æ�¥æœ‰ç‚¹åˆ«æ‰ã€‚å› ä¸ºæ¯�次调用都得创建一个新的åˆ�始值的实例(例å�程åº�ä¸çš„空列表 [] )。
讨论¶
一般æ�¥è®²ï¼Œåˆ›å»ºä¸€ä¸ªå¤šå€¼æ˜ å°„å—典是很简å�•çš„ã€‚ä½†æ˜¯ï¼Œå¦‚æžœä½ é€‰æ‹©è‡ªå·±å®žçŽ°çš„è¯�,那么对于值的åˆ�始化å�¯èƒ½ä¼šæœ‰ç‚¹éº»çƒ¦ï¼Œ ä½ å�¯èƒ½ä¼šåƒ�下é�¢è¿™æ ·æ�¥å®žçŽ°ï¼š
d = {}
for key, value in pairs:
if key not in d:
d[key] = []
d[key].append(value)
如果使用 defaultdict çš„è¯�代ç �å°±æ›´åŠ ç®€æ´�了:
d = defaultdict(list)
for key, value in pairs:
d[key].append(value)
这一å°�节所讨论的问题跟数æ�®å¤„ç�†ä¸çš„记录归类问题有大的关è�”。å�¯ä»¥å�‚考 1.15 å°�节的例å�。