python 模块 collections 专用容器数据类型
文章目录
python 模块 collections 专用容器数据类型
1. 简介
2. 子类
3. 计数器-Counter
3.1 基础介绍
3.2 elements()
3.3 most_common()
3.4 subtract()
3.5 字典方法
3.6 数学操作
4. 双向队列-deque
4.1 append()
4.2 appendleft()
4.3 clear()
4.4 copy()
4.5 count()
4.6 extend()
4.7 extendleft()
4.8 index()
4.9 insert()
4.10 pop()
4.11 popleft()
4.12 remove(value)
4.13 reverse()
4.14 rotate()
4.15 maxlen
5. 有序字典-OrderedDict
5.1 popitem
5.2 move_to_end
5.3 reversed()
6. 命名元组-namedtuple
6.1 与类对比
6.2 加法
6.3 三个方法
6.3.1 _make(iterable)
6.3.2 _asdict()
6.3.3 _replace(**kwargs)
6.4 两个属性
6.4.1 _fields
6.4.2 _field_defaults
6.5 defaults参数
6.6 商取余divmod()函数
6.7 两个坐标
7. 默认字典-defaultdict
7.1 int()
7.2 set
7.3 list()
8. 映射链-ChainMap
8.1 maps
8.2 new_child() 与parents
8.3 ChainMap 变异操作
9. 自定义内置插件:UserString、UserList和UserDict
10. 结论
1. 简介
官方说法:collections模块实现了特定目标的容器,以提供Python标准内建容器dict ,list , set , 和tuple的替代选择。
通俗说法:Python内置的数据类型和方法,collections模块在这些内置类型的基础提供了额外的高性能数据类型,比如基础的字典是不支持顺序的,collections模块的OrderedDict类构建的字典可以支持顺序,collections模块的这些扩展的类用处非常大,熟练掌握该模块,可以大大简化Python代码,提高Python代码逼格和效率。此外,本文的最后一部分需要一些有关Python 中面向对象编程的基本知识。
中文文档
英文文档
2. 子类
用collections.__all__
查看所有的子类,一共包含9个
import collections print(collections.__all__) ['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList', 'UserString', 'Counter', 'OrderedDict', 'ChainMap']
这个模块实现了特定目标的容器,以提供Python标准内建容器dict , list , set , 和tuple 的替代选择。
3. 计数器-Counter
3.1 基础介绍
一个计数器工具提供快速和方便的计数,Counter
是一个dict
的子类,用于计数可哈希对象。它是一个集合,元素像字典键(key)一样存储,它们的计数存储为值。计数可以是任何整数值,包括0和负数,Counter类有点像其他语言中的bags
或multisets
。
#计算top10的单词 from collections import Counter import re text = 'remove an existing key one level down remove an existing key one level down' words = re.findall(r'\w+', text) print(Counter(words).most_common(10)) //[('remove', 2), ('an', 2), ('existing', 2), ('key', 2), ('one', 2), ('level', 2), ('down', 2)] #计算列表中单词的个数 cnt = Counter() for word in ['red', 'blue', 'red', 'green', 'blue', 'blue']: cnt[word] += 1 print(cnt) //Counter({'red': 2, 'blue': 3, 'green': 1}) L = ['red', 'blue', 'red', 'green', 'blue', 'blue'] print(Counter(L)) //Counter({'red': 2, 'blue': 3, 'green': 1}
元素从一个iterable
被计数或从其他的mapping (or counter)
初始化:
from collections import Counter #字符串计数 Counter('gallahad') Counter({'g': 1, 'a': 3, 'l': 2, 'h': 1, 'd': 1}) #字典计数 Counter({'red': 4, 'blue': 2}) Counter({'red': 4, 'blue': 2}) #是个啥玩意计数 Counter(cats=4, dogs=8) Counter({'cats': 4, 'dogs': 8}) Counter(['red', 'blue', 'red', 'green', 'blue', 'blue']) Counter({'red': 2, 'blue': 3, 'green': 1})
3.2 elements()
描述:返回一个迭代器,其中每个元素将重复出现计数值所指定次。 元素会按首次出现的顺序返回。 如果一个元素的计数值小于1,elements() 将会忽略它。
from collections import Counter import re c = Counter(a=4, b=2, c=0, d=-2) print(list(c.elements())) #['a', 'a', 'a', 'a', 'b', 'b'] print(sorted(c.elements())) #['a', 'a', 'a', 'a', 'b', 'b'] c = Counter(a=4, b=2, c=0, d=5) print(list(c.elements())) #['a', 'a', 'a', 'a', 'b', 'b', 'd', 'd', 'd', 'd', 'd']
3.3 most_common()
返回一个列表,其中包含n个最常见的元素及出现次数,按常见程度由高到低排序。 如果 n 被省略或为None,most_common()
将返回计数器中的所有元素,计数值相等的元素按首次出现的顺序排序,经常用来计算top词频的词语。
a=Counter('abracadabra').most_common(3) print(a) #[('a', 5), ('b', 2), ('r', 2)] b=Counter('abracadabra').most_common(5) print(b) #[('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]
3.4 subtract()
从迭代对象或映射对象减去元素。像dict.update()
但是是减去,而不是替换。输入和输出都可以是0或者负数
c = Counter(a=4, b=2, c=0, d=-2) d = Counter(a=1, b=2, c=3, d=4) c.subtract(d) print(c) #Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6}) #减去一个abcd str0 = Counter('aabbccdde') print(str0) #Counter({'a': 2, 'b': 2, 'c': 2, 'd': 2, 'e': 1}) str0.subtract('abcd') print(str0) #Counter({'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1}
3.5 字典方法
通常字典方法都可用于Counter
对象,除了有两个方法工作方式与字典并不相同。
fromkeys(iterable)
这个类方法没有在Counter中实现。
update([iterable-or-mapping])
从迭代对象计数元素或者从另一个映射对象 (或计数器) 添加。 像 dict.update()
但是是加上,而不是替换。另外,迭代对象应该是序列元素,而不是一个 (key, value) 对。
sum(c.values()) # total of all counts c.clear() # reset all counts list(c) # list unique elements set(c) # convert to a set dict(c) # convert to a regular dictionary c.items() # convert to a list of (elem, cnt) pairs Counter(dict(list_of_pairs)) # convert from a list of (elem, cnt) pairs c.most_common()[:-n-1:-1] # n least common elements +c # remove zero and negative counts
3.6 数学操作
这个功能非常强大,提供了几个数学操作,可以结合 Counter 对象,以生产 multisets (计数器中大于0的元素)。 加和减,结合计数器,通过加上或者减去元素的相应计数。交集和并集返回相应计数的最小或最大值。每种操作都可以接受带符号的计数,但是输出会忽略掉结果为零或者小于零的计数。
c = Counter(a=3, b=1) d = Counter(a=1, b=2) c + d # add two counters together: c[x] + d[x] Counter({'a': 4, 'b': 3}) c - d # subtract (keeping only positive counts) Counter({'a': 2}) c & d # intersection: min(c[x], d[x]) Counter({'a': 1, 'b': 1}) c | d # union: max(c[x], d[x]) Counter({'a': 3, 'b': 2})
单目加和减(一元操作符)意思是从空计数器加或者减去。
c = Counter(a=2, b=-4) +c Counter({'a': 2}) -c Counter({'b': 4})
写一个计算文本相似的算法,加权相似
from collections import Counter import re def str_sim(str_0,str_1,topn): topn = int(topn) collect0 = Counter(dict(Counter(str_0).most_common(topn))) collect1 = Counter(dict(Counter(str_1).most_common(topn))) jiao = collect0 & collect1 bing = collect0 | collect1 sim = float(sum(jiao.values()))/float(sum(bing.values())) return(sim) str_0 = '定位手机定位汽车定位GPS定位人定位位置查询' str_1 = '导航定位手机定位汽车定位GPS定位人定位位置查询' print(str_sim(str_0,str_1,5)) #0.75
4. 双向队列-deque
双端队列,可以快速的从另外一侧追加和推出对象,deque
是一个双向链表,针对list连续的数据结构插入和删除进行优化。它提供了两端都可以操作的序列,这表示在序列的前后你都可以执行添加或删除操作。双向队列(deque)对象支持以下方法:
4.1 append()
添加 x 到右端。
from collections import deque d = deque('ghi') d.append('j') print(d) #deque(['g', 'h', 'i', 'j'])
4.2 appendleft()
添加 x 到左端。
from collections import deque d = deque('ghi') d.appendleft('f') print(d) #deque(['f', 'g', 'h', 'i', 'j'])
4.3 clear()
移除所有元素,使其长度为0.
from collections import deque d = deque('ghi') d.clear() print(d) #deque([])
4.4 copy()
创建一份浅拷贝。
from collections import deque d = deque('xiaoweuge') y = d.copy() print(y) #deque(['x', 'i', 'a', 'o', 'w', 'e', 'u', 'g', 'e'])
4.5 count()
计算 deque 中元素等于 x 的个数。
from collections import deque d = deque('xiaoweuge-shuai') print(d.count('a')) #2
4.6 extend()
扩展deque的右侧,通过添加iterable参数中的元素。
from collections import deque a = deque('abc') b = deque('cd') a.extend(b) a #deque(['a', 'b', 'c', 'c', 'd']) #与append 的区别 a = deque('abc') b = deque('cd') a.append(b) print(a) #deque(['a', 'b', 'c', deque(['c', 'd'])])
4.7 extendleft()
扩展deque的左侧,通过添加iterable
参数中的元素。注意,左添加时,在结果中iterable参数中的顺序将被反过来添加。
from collections import deque a = deque('abc') b = deque('cd') a.extendleft(b) print(a) #deque(['d', 'c', 'a', 'b', 'c'])
4.8 index()
返回 x 在 deque 中的位置(在索引 start
之后,索引 stop 之前)。 返回第一个匹配项,如果未找到则引发 ValueError
。
from collections import deque d = deque('xiaoweuge') a=d.index('w') print(a) #4
4.9 insert()
在位置 i 插入 x 。
如果插入会导致一个限长 deque
超出长度 maxlen 的话,就引发一个 IndexError
。
from collections import deque a = deque('abc') e=a.insert(1,'X') print(e) print(a) #None #deque(['a', 'X', 'X', 'b', 'c'])
4.10 pop()
移去并且返回一个元素,deque 最右侧的那一个。 如果没有元素的话,就引发一个 IndexError。
from collections import deque d = deque('xiaoweuge') a = d.pop() print(a) print(d) #e #deque(['x', 'i', 'a', 'o', 'w', 'e', 'u', 'g'])
4.11 popleft()
from collections import deque d = deque('xiaoweuge') a = d.popleft() print(a) print(d) #x #deque(['i', 'a', 'o', 'w', 'e', 'u', 'g', 'e'])
4.12 remove(value)
移除找到的第一个 value。 如果没有的话就引发 ValueError。
from collections import deque a = deque('abca') a.remove('a') print(a) #deque(['b', 'c', 'a'])
4.13 reverse()
将deque逆序排列。返回 None 。
#逆序排列 from collections import deque d = deque('ghi') # 创建一个deque a = list(reversed(d)) b = deque(reversed(d)) print(a) print(b) #['i', 'h', 'g'] #deque(['i', 'h', 'g'])
4.14 rotate()
向右循环移动 n 步。 如果 n 是负数,就向左循环。
如果deque不是空的,向右循环移动一步就等价于 d.appendleft(d.pop())
, 向左循环一步就等价于 d.append(d.popleft())
。
from collections import deque # 向右边挤一挤 d = deque('ghijkl') d.rotate(1) print(d) #deque(['l', 'g', 'h', 'i', 'j', 'k']) # 向左边挤一挤 d.rotate(-1) print(d) #deque(['g', 'h', 'i', 'j', 'k', 'l']) #看一个更明显的 x = deque('12345') print(x) deque(['1', '2', '3', '4', '5']) x.rotate() print(x) #deque(['5', '1', '2', '3', '4']) d = deque(['12','av','cd']) d.rotate(1) print(d) #deque(['cd', '12', 'av'])
4.15 maxlen
Deque的最大尺寸,如果没有限定的话就是 None 。
from collections import deque d=deque(maxlen=10) for i in range(20): d.append(i) print(d) #deque([10, 11, 12, 13, 14, 15, 16, 17, 18, 19], maxlen=10)
除了以上操作,deque还支持迭代、封存、len(d)、reversed(d)、copy.deepcopy(d)、copy.copy(d)、成员检测运算符 in 以及下标引用例如通过 d[0] 访问首个元素等。 索引访问在两端的复杂度均为 O(1) 但在中间则会低至 O(n)。 如需快速随机访问,请改用列表。
Deque从版本3.5开始支持 __add__(), __mul__(), 和 __imul__() 。