collections模块
defaultdict
defaultdict是对Python中字典dict的改善
如果是字典dict:用法是dict={},添加元素是dict[element]=value,调用是dict[element]。
>>>d1 = {'0': '4', '1': '3','2':'2','3':'1','4':'0'}
>>>d1
{'0': '4', '1': '3', '2': '2', '3': '1', '4': '0'}
>>>d1['0']
'4'
但是前提是element是存在于字典的,不然会报KeyError错误。
>>>d1['5']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-16-ae308b3a417e> in <module>
----> 1 d1['5']
KeyError: '5'
这时候你不想返回是一个keyError,而返回一个自己设定的默认值,你会这样写
>>>if '5' in d1:
>>> value = d1['0']
>>>else:
>>> value = '6'
>>>value
'6'
这样调取不存在的键就会返回默认值6。
使用get方法
不过字典的get方法可以返回一个默认值,因此可以简写为
>>>d1.get('5','6')
'6'
不过带有默认值的get方法会在key参数还不是字典的键时返回None,一个常见的场景是字典中的值集合通过设置,成立另一个集合,比如列表。比如你想把一些单词按首字母归类
words = ['apple', 'bat', 'bar', 'atom', 'book']
by_letter = {}
for word in words:
letter = word[0]
if letter not in by_letter:
by_letter[letter] = [word]
else:
by_letter[letter].append(word)
by_letter
{'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}
如果使用get方法写,返回一个空字典如下
words = ['apple', 'bat', 'bar', 'atom', 'book']
by_letter = {}
for word in words:
letter = word[0]
by_letter.get(letter, []).append(word)
by_letter
{}
使用dict.setdefault()方法
所以这时候就需要用到dict.setdefault()方法,先来看setdefault()方法的定义D.setdefault(k[,d])->D.get(k,d),also set D[k]=d if k not in D。所以它等于说先是和get方法一样接收两个参数,第一个参数是健的名称,第二个参数是你想要的默认值。并增加了一个判断语句,假如字典中不存在给定的键,则返回参数中提供的默认值;反之,则返回字典中保存的值。那么上面的代码可以简化为:
words = ['apple', 'bat', 'bar', 'atom', 'book']
by_letter = {}
for word in words:
letter = word[0]
by_letter.setdefault(letter, []).append(word)
by_letter
{'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']}
使用collections.defaultdict类
那defaultdict类是一个更简单的方法,而且返回的不单单是你设定的默认值,还可以是任何资料形态,比如list, set,tuple等等。
语法公式:
collections.defaultdict([default_factory[, …]])
如果转入list。当字典中没有的键第一次出现时,default_factory自动为其返回一个空列表,list.append()会将值添加进新列表;再次遇到相同的键时,list.append()将其它值再添加进该列表。那上次例子就可以这样写
words = ['apple', 'bat', 'bar', 'atom', 'book']
from collections import defaultdict
by_letter = defaultdict(list)
for word in words:
by_letter[word[0]].append(word)
by_letter
defaultdict(list, {'a': ['apple', 'atom'], 'b': ['bat', 'bar', 'book']})
比如转入int如下:
from collections import defaultdict
s = 'mississippi'
d = defaultdict(int)
for k in s:
d[k] += 1
print('\n',d)
a=sorted(d.items())
print('\n',a)
结果:
defaultdict(<class 'int'>, {'m': 1, 'i': 4, 's': 4, 'p': 2})
[('i', 4), ('m', 1), ('p', 2), ('s', 4)]
或者传入set
from collections import defaultdict
s = [('red', 1), ('blue', 2), ('red', 3), ('blue', 4), ('red', 1), ('blue', 4)]
d = defaultdict(set)
for k, v in s:
d[k].add(v)
print('\n',d)
a=sorted(d.items())
print('\n',a)
结果:
defaultdict(<class 'set'>, {'red': {1, 3}, 'blue': {2, 4}})
[('blue', {2, 4}), ('red', {1, 3})]