collections模块

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}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355