python-collections
collections是Python内建的一个集合模块,提供了许多有用的集合类和方法。
可以把它理解为一个容器,里面提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择。
import collections
print(dir(collections))
# ['ChainMap', 'Counter', 'Mapping', 'MutableMapping', 'OrderedDict', 'UserDict', 'UserList',
#'UserString', '_Link', '_OrderedDictItemsView', '_OrderedDictKeysView',
#'_OrderedDictValuesView', '__all__', '__builtins__', '__cached__', '__doc__', '__file__',
#'__getattr__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '_chain',
#'_collections_abc', '_count_elements', '_eq', '_heapq', '_iskeyword', '_itemgetter',
#'_nt_itemgetters', '_proxy', '_recursive_repr', '_repeat', '_starmap', '_sys', 'abc',
#'defaultdict', 'deque', 'namedtuple']
2.常用方法
namedtuple : 创建一个命名元组子类的工厂函数
deque : 高效增删改双向列表,类似列表(list)的容器,
实现了在两端快速添加(append)和弹出(pop)
defaultdict : 当字典查询时,为key不存在提供一个默认值。
OrderedDict: 有序词典,就是记住了插入顺序
Counter : 计数功能
1、namedtuple 具名元组
参数
collections.namedtuple(typename, field_names, *, rename=False,
defaults=None, module=None)
typename : 命名的名字,返回一个新的元组子类,名为 typename
field_names : 可以是一个[‘x’, ‘y’]这样的序列,也可以是’x, y’或者’x y’
rename : python3.1添加,如果 rename 为真, 无效域名会自动转换成位置名。比如 [‘abc’, ‘def’, ‘ghi’, ‘abc’] 转换成 [‘abc’, ‘_1’, ‘ghi’, ‘_3’] , 消除关键词 def 和重复域名 abc 。
defaults : python3.7添加, defaults 可以为 None 或者是一个默认值的 iterable(可迭代对 象)。如果一个默认值域必须跟其他没有默认值的域在一起出现, defaults 就应用到最右边的参数。比如如果域名 [‘x’, ‘y’, ‘z’] 和默认值 (1, 2) ,那么 x 就必须指定一个参数值 ,y 默认值 1 , z 默认值 2 。
module : python3.6添加,如果 module 值有定义,命名元组的 __module__属性值就被设置。
from collections import namedtuple
Person = namedtuple('Person', ['name', 'age', 'addr'])
person = Person('Gavin', '22', 'Shenyang')
print(person) # Person(name='Gavin', age='22', addr='Shenyang')
'''方法的使用'''
print(person._fields) # ('name', 'age', 'addr')
print(person._asdict()) # {'name': 'Gavin', 'age': '22', 'addr': 'Shenyang'}
print(person.name) # Gavin
print(person._replace(name='Gavin_test')) # Person(name='Gavin_test', age='22', addr='Shenyang')
'''用 isinstance 判断其类型'''
print(isinstance(person, Person)) # True
print(isinstance(person, tuple)) # True
new_person = Person._make(['Venna', '23', 'Shenzhen'])
print(new_person) # Person(name='Venna', age='23', addr='Shenzhen')
2、deque 双端队列
参数
collections.deque([iterable[, maxlen]])
返回一个新的双向队列对象,从左到右初始化(用方法 append()) ,从 iterable (迭代对象) 数据创建。如果 iterable 没有指定,新队列为空。
iterable :迭代对象,可以是字符串,列表等可迭代对象。
maxlen : maxlen 没有指定或者是 None , deque 可以增长到任意长度。否则, deque 就限定到指定最大长度。一旦限定长度的 deque 满了,当新项加入时,同样数量的项就从另一端弹出。
from collections import deque
q = deque(['a', 'b', 'c'], maxlen=10)
# 从右边添加一个元素
q.append('d')
print(q) # deque(['a', 'b', 'c', 'd'], maxlen=10)
# 从左边删除第一个元素
print(q.popleft()) # a
print(q) # deque(['b', 'c', 'd'], maxlen=10)
# 从右边删除第一个元素
print(q.pop()) # d
print(q) # deque(['b', 'c'], maxlen=10)
# 扩展队列
q.extend(['i', 'j'])
print(q) # deque(['b', 'c', 'd', 'i', 'j'], maxlen=10)
# 查找下标
print(q.index('c')) # 1
# 移除第一个'd'
q.remove('d')
print(q) # deque(['b', 'c', 'i', 'j'], maxlen=10)
# 逆序
q.reverse()
print(q) # deque(['j', 'i', 'c', 'b'], maxlen=10)
# 最大长度
print(q.maxlen) # 10
append(x):添加 x 到右端。
appendleft(x):添加 x 到左端。
clear():移除所有元素,使其长度为0.
copy():创建一份浅拷贝。3.5 新版功能.
count(x):计算deque中个数等于 x 的元素。3.2 新版功能.
extend(iterable):扩展deque的右侧,通过添加iterable参数中的元素。
extendleft(iterable):扩展deque的左侧,通过添加iterable参数中的元素。注意,左添加时,在结果中iterable参数中的顺序将被反过来添加。
index(x[, start[, stop]]):返回第 x 个元素(从 start 开始计算,在 stop 之前)。返回第一个匹配,如果没找到的话,升起 ValueError 。3.5 新版功能.
insert(i, x):在位置 i 插入 x 。如果插入会导致一个限长deque超出长度 maxlen 的话,就升起一个 IndexError 。3.5 新版功能.
pop():移去并且返回一个元素,deque最右侧的那一个。如果没有元素的话,就升起 IndexError 索引错误。
popleft():移去并且返回一个元素,deque最左侧的那一个。如果没有元素的话,就升起 IndexError 索引错误。
remove(value):移去找到的第一个 value。 如果没有的话就升起 ValueError 。
reverse():将deque逆序排列。返回 None 。3.2 新版功能.
rotate(n=1):向右循环移动 n 步。 如果 n 是负数,就向左循环。如果deque不是空的,向右循环移动一步就等价于 d.appendleft(d.pop()) , 向左循环一步就等价于 d.append(d.popleft()) 。
Deque对象同样提供了一个只读属性:
maxlen:Deque的最大尺寸,如果没有限定的话就是 None 。
3、defaultdict()
defaultdict是Python内建字典类(dict)的一个子类,它重写了方法_missing_(key),
增加了一个可写的实例变量default_factory,实例变量default_factory被missing()方法使用,如果该变量存在,则用以初始化构造器,如果没有,则为None。其它的功能和dict一样。
- 使用list作第一个参数,可以很容易将键-值对序列转换为列表字典。
#!/usr/bin/python
from collectionsimport defaultdict
s = [('yellow',1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
d =defaultdict(list)
for k,v in s:
d[k].append(v)
print(d.items()
-->* [('blue', [2, 4]),('red', [1]), ('yellow', [1, 3])]
当字典中没有的键第一次出现时,default_factory
自动为其返回一个空列表,list.append()
会将值添加进新列表;
再次遇到相同的键时,list.append()
将其它值再添加进该列表。
这种方法比使用dict.setdefault()
更为便捷,dict.setdefault()
也可以实现相同的功能。
- 计数
from collectionsimport defaultdict
s = 'mississippi'
d =defaultdict(int)
for k in s:
d[k] += 1
print(d.items())
-->* [('i', 4), ('p',2), ('s', 4), ('m', 1)]
3 使用默认值
from collections import defaultdict
dd = defaultdict(lambda: 'not exist')
dd['key1'] = 'abc'
print(dd['key1']) # key1存在
# 'abc'
print(dd['key2']) # key2不存在,返回默认值
# 'not exist'
4 、setdefault()
提供了一种方式,在一行中完成这件事。传递给该方法的第一 个参数,
是要检查的键。第二个参数,是如果该键不存在时要设置的值。如果该键 确实存在,方法就会返回键的值
spam = {'name': 'Pooka', 'age': 5}
spam.setdefault('color', 'black')
--> {'name': 'Pooka', 'age': 5, 'color': 'black'}
*s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
d={}
for k, v in s:
d.setdefault(k,[]).append(v)
a=sorted(d.items())
--> {'yellow': [3, 4], 'blue': [3, 4], 'red': 1}
*笨方法:
a = {}
d = []
for k, v in s:
if k in a:
d.append(v)
a[k] = d
else:
a[k] = v
print(a)
--> {'yellow': [3, 4], 'blue': [3, 4], 'red': 1}
5、OrderedDict 有序字典
from collections import OrderedDict
'''last = True 代表是否最后'''
d = OrderedDict(a=1, b=2, c=3, d=4, e=5)
print(d) # OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)])
print(d.popitem(last=True)) # ('e', 5)
print(d.popitem(last=False)) # ('a', 1)
print(d) # OrderedDict([('b', 2), ('c', 3), ('d', 4)]
'''move_to_end 移动元素的位置'''
dd = OrderedDict(a=1, b=2, c=3, d=4, e=5)
# OrderedDict([('b', 2), ('c', 3), ('d', 4), ('e', 5), ('a', 1)])
dd.move_to_end(key='a', last=True)
# OrderedDict([('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5)])
dd.move_to_end(key='a', last=False)
print(dd)
6、Counter 计数
Counter 是一个 dict 的子类,用于计数可哈希对象。
from collections import Counter
'''Str 类型计数'''
c = Counter()
c2 = Counter('aaabbbcccdddee')
print(c2) # Counter({'a': 3, 'b': 3, 'c': 3, 'd': 3, 'e': 2})
''' list 类型计数'''
l = Counter(['red', 'blue', 'red', 'green', 'blue', 'blue'])
print(l) # Counter({'blue': 3, 'red': 2, 'green': 1})
'''elements() :返回一个迭代器,其中每个元素将重复出现计数值所指定次。'''
e = Counter({'blue': 3, 'red': 2, 'green': 1})
print(sorted(e.elements())) # ['blue', 'blue', 'blue', 'green', 'red', 'red']
'''most_common([n]) :返回一个列表,其中包含 n 个最常见的元素及出现次数,按常见程度由高到低排序'''
m = Counter('aaabbbcccdddeeee')
print(m.most_common(4))