collections是python内建的集合模块,提供了许多有用的集合类
nametuple
将元祖由索引下标调用改为由像类调用属性那样调用
示例:
普通元祖的调用方式
tuple1 = (1, 2)
print(tuple1[0]) # 普通元祖通过下标获取数据
>>1
print(tuple1[1])
>>2
nametuple的调用方式:以定义一个点Point为例,也是python源码示例
from collections import namedtuple
Point = namedtuple("Point",["x","y"])
tp1 = Point(1,2)
print(Point.__doc__) # Point(x, y)
# 转换为nametuple之后,依然可以像元祖那样调用,相当于多了一种调用的方式
print(tp1[0]) # 1
print(tp1.x) # 1
print(tp1[1]) # 2
print(tp1.y) # 2
x, y = tp1 # tuple unpack 元祖解包
print(x,y) # 1 2
dict_tp1 = tp1._asdict() # convert nametuple to OrderedDict
print(dict_tp1) # OrderedDict([('x', 1), ('y', 2)])
print(dict_tp1["x"]) # 1
tp3 = tp1._replace(x=100) # 元祖不可变,所以这里实际是生成了一个新的对象返回,类型字符串的替换
print(tp3.x) # 100
dict1 = {"x":10,"y":20}
tp2 = Point(**dict1) # pass parameter with unpack from a dictionary
print(tp2) # Point(x=10, y=20)
print(tp2.x) # 10
deque双端队列(列表)
使用list
存储数据时,利用下标索引访问很快,但是插入和删除元素就很慢了.因为list
的数据结构是线性表结构,每插入一个数据,该插入点之后的数据都要往后迁移一格(为了保证有序性),所以效率会低,deque是为了高效实现插入和删除操作的双向列表,适用于队列和栈
from collections import deque
list1 = [0,1,2,3,1,1]
deq = deque(list1)
print(deq) # deque([0, 1, 2, 3, 1, 1])
print(deq[1]) # 1
deq.append(4)
deq.appendleft(-1)
print(deq) # deque([-1, 0, 1, 2, 3, 1, 1, 4])
print(deq.count(1)) # 3
deq.extend([5, 6]) # deque 也可以拼接普通的列表
deq.extendleft(deque([-3,-2])) # 拼接deque列表
print(deq) # deque([-2, -3, -1, 0, 1, 2, 3, 1, 1, 4, 5, 6])
pop_right1 = deq.pop() # 删除最后一个
pop_left1 = deq.popleft() # 删除第一个
print(pop_left1,pop_right1,deq) # -2 6 deque([-3, -1, 0, 1, 2, 3, 1, 1, 4, 5])
# 普通列表支持指定索引删除,deque不支持,下面写的方式会报错
# pop_index = deq.pop(2) # 注意不能这样写,普通列表可以指定索引删除,但是deque不可以
# 指定元素删除
num = deq.remove(0) # 注意remove 不像pop 那样有返回值.remove操作不返回结果
print(num,deq) # None deque([-3, -1, 1, 2, 3, 1, 1, 4, 5])
# 因为deque是可变数据类型,所以reverse操作是直接修改原数据,而不是生成新数据返回
reverse_deque = deq.reverse()
print(reverse_deque,deq) # None deque([5, 4, 1, 1, 3, 2, 1, -1, -3])
# rotate旋转操作(也可以理解为平移,超出边界后从头挪到尾或从尾挪到头),接收一个参数n,
# 当n为整数时,所有数据整体向右平移n个位置.n为负数,向左平移n个位置
# deque可变类型, rotate操作同样时改变原数据,非生成新数据返回
rotate_deque = deq.rotate(1)
print(rotate_deque,deq) # None deque([-3, 5, 4, 1, 1, 3, 2, 1, -1])
# clear 清空deque
# clear 清空deque
print(deq.clear(),deq) # None deque([])
print(len(deq)) # 0
defaultdict
defaultdict
在初始化的时候,默认传递None
,即取不存在的key
时,会抛出keyerror
,想要key
不存在时,需要传递一个可调用的参数进去,这里我们选择了使用匿名函数(写法简洁)当做参数传递,普通字典的get
方法也可以达到返回默认值的情况
from collections import defaultdict
dict1 = defaultdict(lambda :"haha")
print(dict1["a"]) # haha
dict1["a"] = 11
print(dict1["a"]) # 11
# 普通dict
dict1 = {"a":1}
print(dict1.get("a")) # 1
print(dict1.get("b")) # None
print(dict1.get("b","haha")) # haha
OrderDict
OrderDict
不会改变插入字典的键值对的顺序,其他功能和普通字典一样
from collections import OrderedDict
list1 = [(1,2),(2,3),(3,4),(4,5),(5,6),(6,7)]
dict1 = OrderedDict(list1)
print(dict1)
>>OrderedDict([(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)])
print(dict1.popitem()) # last default True;default pop last item ; while last is False,the first item will be pop
>>(6, 7)
print(dict1.popitem(last=False)) # the first item will be pop, return tuple
>>(1, 2)
print(dict1.pop(3)) # return the key corresponding to the value
>>4
print(dict1)
>>OrderedDict([(2, 3), (4, 5), (5, 6)])
利用有序字典创建一个FIFO(先进先出)的字典队列,超出上限,删除第一个元素
from collections import OrderedDict
class FIFO_dict(OrderedDict):
def __init__(self,max_value,*args,**kwargs):
super(FIFO_dict, self).__init__(*args,**kwargs)
self.max_value = max_value
def __setitem__(self, key, value):
current_len = len(self)
is_need_update = 0 if key not in self else 1
is_need_pop_left_item = 1 if current_len - is_need_update >= self.max_value else 0
if is_need_update: # is_need_update 为 1 的时候 is_need_pop_left_item 一定会是0
self.pop(key)
if is_need_pop_left_item:
self.popitem(last=False)
super(FIFO_dict, self).__setitem__(key,value)
def get_first(self):
return self.popitem(last=False)
fifo1 = FIFO_dict(3)
fifo1[0] = 0
fifo1[1] = 1
fifo1[2] = 2
print(fifo1)
>>FIFO_dict([(0, 0), (1, 1), (2, 2)])
fifo1[3] = 3
print(fifo1)
>>FIFO_dict([(1, 1), (2, 2), (3, 3)])
fifo1[2] = 4
print(fifo1)
>>FIFO_dict([(1, 1), (3, 3), (2, 4)])
print(fifo1.get_first())
>>(1, 1)
Counter
Counter
是一个计数器,可以统计放入元素出现的次数
from collections import Counter
str1 = "adawq112eadd"
c1 = Counter()
for s in str1:
c1[s] = c1[s] + 1
print(c1)
>>Counter({'d': 3, 'a': 3, '1': 2, 'q': 1, '2': 1, 'e': 1, 'w': 1})
自己实现一个Counter
class MyCounter(object):
def __init__(self):
self.map = dict()
def set_ele(self,key):
if key not in self.map:
self.map[key] = 0
self.map[key] += 1
def __repr__(self):
return "{}".format(self.map)
str2 = "adawq112eadd"
mycounter = MyCounter()
for data in str2:
mycounter.set_ele(data)
print(mycounter)
>>{'q': 1, '2': 1, 'e': 1, 'd': 3, 'a': 3, 'w': 1, '1': 2}
网友评论