python-collections

python-collections

总述

Python数据结构常用模块:collectionsheapqoperatoritertools

高性能容器数据类型

import collections
print(collections.__all__)
['deque', 'defaultdict', 'namedtuple', 'UserDict', 'UserList', 
'UserString', 'Counter', 'OrderedDict', 'ChainMap']
模块 说明
1 Counter 字典的子类,提供了可哈希对象的计数功能
2 deque 类似列表(list)的容器,实现了在两端快速添加(append)和弹出(pop)
3 OrderedDict 字典的子类,保存了他们被添加的顺序
4 defaultdict 字典的子类,提供了一个工厂函数,为字典查询提供一个默认值
5 namedtuple 创建命名元组子类的工厂函数
6 ChainMap 类似字典(dict)的容器类,将多个映射集合到一个视图里面
7 UserDict 封装了字典对象,简化了字典子类化
8 UserList 封装了列表对象,简化了列表子类化
9 UserString 封装了列表对象,简化了字符串子类化

1-Counter计数器

计数器,继承于 dict , 用于计算 hashtable

Counter 类的目的是用来跟踪统计值出现的次数,无序数据类型

以键值对的形式存储,

其中元素作为key,其计数作为value

#统计词频
colors = ['red', 'blue', 'red', 'green', 'blue', 'blue']
result = {}
for color in colors:
    if result.get(color)==None:
        result[color]=1
    else:
        result[color]+=1
print (result)
#{'red': 2, 'blue': 3, 'green': 1}

# 下面是Counter 的使用方法
from collections import Counter
colors = ['red', 'blue', 'red', 'green', 'blue', 'blue']
c = Counter(colors)
print (dict(c))

创建

collections.Counter([iterable-or-mapping])

# 支持传入 list,tuple,dict, str 等 iterable  or mapping 类型

c = Counter()  			        # 创建一个空的Counter类

c = Counter('gallahad')         # 可iterable对象<list、tuple、dict、字符串>
c = Counter({'a': 4, 'b': 2})   # 从一个 dict 对象创建
c = Counter(a=4, b=2)  			# 从一组键值对创建
 
# Counter对象有一个字典接口,如果引用的键没有任何记录,就返回一个0
c = Counter(['eggs', 'ham'])
c['apple']=0

属性和方法

方法 描述
most_common(n) 从高到低的排序,返回前n个元素,返回[('':5),('':3),..]
elements() 返回迭代器,Counter内所有元素
update(counter) 不同于dict这里values值是计数加法而不是覆盖,直接更新无返回值
substract(cout) 和update类似,update是做加法,substract是对values计数减法
items()
keys()
values()
#-----------------------------------------------------------\
#element
c = Counter(a=4, b=2, c=0, d=-2)
print(list(c.elements()))
#['a', 'a', 'a', 'a', 'b', 'b']

print(list(c.elements()))
#['a', 'a', 'a', 'a', 'b', 'b', 'd', 'd', 'd', 'd', 'd']

#-----------------------------------------------------------
#most_common()
count=Counter('abracadabra')
print(count.most_common())
#[('a', 5), ('b', 2), ('r', 2), ('c', 1), ('d', 1)]

print(count.most_common(n=3))   # 前3个
#[('a', 5), ('b', 2), ('r', 2)]

#-----------------------------------------------------------
#update([iterable-or-mapping])  可以是 list str dict

count=Counter([1,2,3,4,5,1,3,2,])
print(cout)
#Counter({1: 2, 2: 2, 3: 2, 4: 1, 5: 1})

count.update([3, 1, 4, 5, 1])
print(count)
#Counter({1: 4, 3: 3, 2: 2, 4: 2, 5: 2, 7: 1})

#-----------------------------------------------------------
#subtract()
cout1 = Counter(a=4, b=2, c=0, d=-2)
cout2 = Counter(a=1, b=2, c=3, d=4)
print(cout1)
cout1.subtract(cout2)
print(cout1)
#Counter({'a': 4, 'b': 2, 'c': 0, 'd': -2})
#Counter({'a': 3, 'b': 0, 'c': -3, 'd': -6})


cout3 = Counter('aabbccdde')
cout4 = Counter('abcd')
print(cout3)
cout3.subtract(cout4)
print(cout3)
#Counter({'a': 2, 'b': 2, 'c': 2, 'd': 2, 'e': 1})
#Counter({'a': 1, 'b': 1, 'c': 1, 'd': 1, 'e': 1}) 

#-----------------------------------------------------------
#相互之间的数据集合操作
c = Counter(a=3, b=1, c=5)
d = Counter(a=1, b=2, d=4)

c+d			    counter相加,相同 key的value 相加
c-d				counter相减,相同 key的value 相减 
c&d             交集  取c,d两者中 value 取值小的那个
c|d 			并集  取c,d两个中 value 取值大的那个



c = Counter(a=3, b=1)
d = Counter(a=1, b=2)
f1=c+d
print(f1)
f2=c-d
print(f2)
#Counter({'a': 4, 'b': 3})
#Counter({'a': 2})

#-----------------------------------------------------------
其他dict属性
c = Counter(a=5,b=4,c=3)
c.items()			# dict items()
c.keys()			# dict keys()
c.values()

c['a'] = 5  		# dict 获取元素	
c.get('a')=5		# 获取元素
		
del c['c']			# dict 删除元素
c.pop()		
c.clear()

2-deque队列

dqueue 是 ”double-ended queue” 的简称, deque属于高性能的数据结构之一

双端队列(deque)具有从任一端添加和删除元素的功能

它的操作很像list 同时

相比于list实现的队列,deque实现拥有更低的时间和空间复杂度。list实现在出队(pop)和插入(insert)时的空间复杂度大约为O(n),deque在出队(pop)和入队(append)时的时间复杂度是O(1)。

所以deque更有优越性 而且deque既可以表示队列

创建

from collections import deque
 
d = deque()

属性和方法

方法 描述
append() 添加元素到右端
appendleft() 左端
extend() 添加iterable对象到右端
extendleft() 左端,结果中iterable参数中的顺序将被反过来添加
insert() 在位置 i 插入 x 。
pop() 移去并且返回一个元素,最右端
popleft() 移去并且返回一个元素,最左端
rotate(n=1) 向右循环移动 n 步。 如果 n 是负数,就向左循环
maxlen Deque的最大尺寸,如果没有限定的话就是 None, 无括号
reverse() 反转
remove(value) 移除找到的第一个 value
index() 返回索引位置,不存在则ValueError
count() 计算 deque 中元素等于 x 的个数
clear()
copy()
#--------------------------------------------------------
#apppend appendleft
dp=deque(list(range(6)))
dp.append(5)
print(dp)

dp.appendleft(-5)
print(dp)

#deque([0, 1, 2, 3, 4, 5, 5])
#deque([-5, 0, 1, 2, 3, 4, 5, 5])

#-------------------------------------------------------
#expend expendleft
dp2=deque(list(range(6)))
dp2.extend(list(range(8,11)))
print(dp2)

dp2.extendleft([1,2,3,4])
print(dp2)
#deque([0, 1, 2, 3, 4, 5, 8, 9, 10])
#deque([4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 8, 9, 10])

##-------------------------------------------------------
#pop popleft
dp2=deque(list(range(8)))

res1=dp2.pop()
res2=dp2.popleft()

print(dp2,',',res1,res2)
#deque([1, 2, 3, 4, 5, 6]) , 7 0

##-------------------------------------------------------
# remove
a = deque('abca')
a.remove('a')
print(a)
#deque(['b', 'c', 'a'])

##-------------------------------------------------------
#rotate()
dp2=deque(list(range(8)))

print(dp2)
dp2.rotate(3)
print(dp2)

#deque([0, 1, 2, 3, 4, 5, 6, 7])
#deque([5, 6, 7, 0, 1, 2, 3, 4])

##-------------------------------------------------------
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])

##-------------------------------------------------------
d = deque('xiaoweuge-shuai')
print(d.count('a'))
2

3-OrderedDict

OrderedDict 是字典的子类,保证了元素的插入顺序。在 3.7 版本下,字典同样也保证了元素的插入顺序。那相比内置字典 OrderedDict 有哪些升级呢

  • OrderedDict 继承 dict

  • 常规的 dict 被设计为非常擅长映射操作。 跟踪插入顺序是次要的

  • OrderedDict 旨在擅长重新排序操作。 空间效率、迭代速度和更新操作的性能是次要的

  • OrderedDict 类有一个 move_to_end() 方法,可以有效地将元素移动到任一端。

属性方法 描述
popitem() 移除并返回一个 (key, value) 键值对
move_to_end(key) 把指定键值对移动到最后
clear ,fromkeys,get 其他继承方法
items,keys,pop,update,values 其他继承方法x

创建

import collections
dic = collections.OrderedDict()
dic['k1'] = 'v1'
dic['k2'] = 'v2'
dic['k3'] = 'v3'
print(dic)

#输出:OrderedDict([('k1', 'v1'), ('k2', 'v2'), ('k3', 'v3')])

属性和方法

fromkeys()

fromkyes(iter,value)
# 由 序列 构造 字典   key 值不同,value 相同
"""
输入参数 	
iter    	序列,list,tuple
value		value的值
"""

dict=dict()
seq = [1,2,3]
dict = dict.fromkeys(seq,"icom")
print(dict)
{1: 'icom', 2: 'icom', 3: 'icom'}

##-------------------------------------------------------
d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2}
d = OrderedDict(d)
print(d)
res=d.popitem()
print(res)
print(d)
#OrderedDict([('banana', 3), ('apple', 4), ('pear', 1), ('orange', 2)])
#('orange', 2)
#OrderedDict([('banana', 3), ('apple', 4), ('pear', 1)])

##-------------------------------------------------------
d = OrderedDict([('a', 'A'), ('b', 'B'), ('c', 'C')])
print(d)
d.move_to_end('b')
print(d)

#OrderedDict([('a', 'A'), ('b', 'B'), ('c', 'C')])
#OrderedDict([('a', 'A'), ('c', 'C'), ('b', 'B')])

4-defaultdict

返回一个新的类似字典的对象。 defaultdict是内置dict类的子类。它重载了一个方法并添加了一个可写的实例变量

一个需求案例

将(键-值对组成的)序列转换为(键-列表组成的)字典

data = [("p", 1), ("p", 2), ("p", 3),
		("h", 1), ("h", 2), ("h", 3)]
转换成 result = {'p': [1, 2, 3], 'h': [1, 2, 3]}
#方法一
result = {}
for (key, value) in data:
    if key in result:
        result[key].append(value)
    else:
        result[key] = [value]
        
##-------------------------------------------------------
#方法二
result = {}
data = [("p", 1), ("p", 2), ("p", 3),
        ("h", 1), ("h", 2), ("h", 3)]
for (key, value) in data:
    result.setdefault(key, []).append(value)
print(result)#'p': [1, 2, 3], 'h': [1, 2, 3]}

##-------------------------------------------------------
#方法三
from collections import defaultdict
result = defaultdict(list)
data = [("p", 1), ("p", 2), ("p", 3),
        ("h", 1), ("h", 2), ("h", 3)]
 
for (key, value) in data:
    result[key].append(value)
print(result)
#defaultdict(<class 'list'>, {'p': [1, 2, 3], 'h': [1, 2, 3]})


##-------------------------------------------------------
# defaultdict(list) 使用list方法
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
dic = defaultdict(list)

for i in s:
    dic[i[0]].append(i[1])
dic = dict(dic)
print(dic)
for i in dic:
    dic[i] = sum(dic[i])
print(dic)

#{'yellow': [1, 3], 'blue': [2, 4], 'red': [1]}
#{'yellow': 4, 'blue': 6, 'red': 1}


##-------------------------------------------------------
#defaultdict(set) 使用set 方法
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(d)
defaultdict(<class 'set'>, {'red': {1, 3}, 'blue': {2, 4}})

5-namedtuple

namedtuple(typename, field_names, rename=False, defaults=None, module=None)

返回一个新的元组子类,名为 typename 。这个新的子类用于创建类元组的对象,可以通过字段名来获取属性值,同样也可以通过索引和迭代获取值

from collections import namedtuple
# 定义命名元组类:Point

# 创建的是一个类,需要进行实例化
Point = namedtuple('Point', ['x', 'y'])
p = Point(11, y=22)
print(p)
print(p[0],p[1],'11+22=',p[0]+p[1])
x,y=p
print(p.x*p.y)

#Point(x=11, y=22)
#11 22 11+22= 33
#242
属性方法 描述
_make() 类方法从存在的序列或迭代实例创建一个新实例
_asdict() 返回一个新的 dict ,它将字段名称映射到它们对应的值
_replace(**kwargs) 返回一个新的命名元组实例,并将指定域替换为新的值
_fields 从现有元组创建一个新的命名元组类型
_field_defaults 映射默认值
Point = namedtuple('Point', ['x', 'y'])
p = Point(11, y=22)
t = [22, 44]
p1=Point._make(t)
print(p1)

p2=p1._asdict()
print(p2)

#Point(x=22, y=44)
#{'x': 22, 'y': 44}

p = Point(x=11, y=22)
p3=p._replace(x=55)
print(p3)
#Point(x=55, y=22)

#----------------------------------------------------------
Point = namedtuple('Point', ['x', 'y'])
print(p._fields)
Color = namedtuple('Color', 'red green blue')
Pixel = namedtuple('Pixel', Point._fields + Color._fields)
pix=Pixel(11, 22, 128, 255, 0)
print(pix)

#('x', 'y')
#Pixel(x=11, y=22, red=128, green=255, blue=0)


Account = namedtuple('Account', ['type', 'balance'], defaults=[0])
Account._field_defaults
print(Account._field_defaults)

acc=Account('premium')
print(acc)

#{'balance': 0}
#Account(type='premium', balance=0)

6-ChainMap-映射链

为了将多个映射快速的链接到一起,这样它们就可以作为一个单元处理

dcic1 = {'label1': '11', 'label2': '22'}
dcic2 = {'label2': '22', 'label3': '33'}
dcic3 = {'label4': '44', 'label5': '55'}
last  = ChainMap(dcic1, dcic2,dcic3)
print(last)
# ChainMap({'label1': '11', 'label2': '22'}, {'label2': '22', 'label3': '33'}, {'label4': '44', 'label5': '55'})
方法 描述
maps 返回映射
new_child(m=None) 返回一个新的ChainMap类,一个新映射(map),跟随当前实例的全部映射map
parents 属性返回一个新的ChainMap包含所有的当前实例的映射,除了第一个
dcic1 = {'label1': '11', 'label2': '22'}
dcic2 = {'label1': '22', 'label2': '33'}
dcic3 = {'label4': '44', 'label5': '55'}
chain=ChainMap(dcic1, dcic2,dcic3)

print(chain)
print(chain.parents)
print(chain.maps)
print(list(chain))

#ChainMap({'label1': '11', 'label2': '22'}, {'label1': '22', 'label2': '33'}, {'label4': '44', 'label5': '55'})
#ChainMap({'label1': '22', 'label2': '33'}, {'label4': '44', 'label5': '55'})
#[{'label1': '11', 'label2': '22'}, {'label1': '22', 'label2': '33'}, {'label4': '44', 'label5': '55'}]
#['label4', 'label5', 'label1', 'label2']


#---------------------------------------------------------
chain.new_child(m={'key_new':888})
print(chain)
#ChainMap({'label1': '11', 'label2': '22'}, {'label1': '22', 'label2': '33'}, {'label4': '44', 'label5': '55'})   

posted @ 2021-07-23 22:30  贝壳里的星海  阅读(64)  评论(0编辑  收藏  举报