Python中的collections模块(三) 命名元组namedtuple和双端队列deque

前言

Python 内置模块collections, 目标是提供各种专门的集合数据类型来解决特定的编程问题。

本系列介绍其中的数据结构特点和使用方法,  以便遇到某些特定的问题,可以找到对应的数据来处理, 达到事半功倍的效果

⭐namedtuple用于创建其子类的工厂函数tuple,提供命名字段,允许按名称访问项目,同时保持按索引访问项目的能力
⭐deque一个类似序列的集合,支持从序列的任一端有效地添加和删除项目
OrderedDict根据插入键的时间保持键值对排序的字典子类
ChainMap一个类似字典的类,允许将多个映射视为单个字典对象
defaultdict一个字典子类,用于为缺失的键构建默认值并自动将它们添加到字典中
Counter一个字典子类,支持方便地对序列或可迭代中的唯一项进行计数

本文介绍其中两个 namedtuple,  deque​​​​​​​, 其他的可以参考

Python中的collections模块(一) 使用Counter,pythonic的对象计数方式

Python中的collections模块(二) 有序字典OrderedDict和链接字典ChainMap

Python中的collections模块(四) UserString,UserList,和UserDict​​​​​​​

1. 使用namedtuple提高代码可读性

tuple(元组)是python内置的数据结构,是一种不可变的有序数据集合.通过坐标索引来访问数据

In [1]: card = ('Spades', '7')

In [2]: card[0]
Out[2]: 'Spades'

使用namedtuple可以创建命名字段的tuple。可以使用点表示法和字段名称访问给定命名元组中的值,如obj.attr. 使用方式:namedtuple(typename:str, field_names:list or tuple)

In [3]: from collections import namedtuple

In [4]: Card = namedtuple('Cards', ['suit', 'rank'])

In [5]: spade_7 = Card('spades', '7')
In [6]: spade_7
Out[6]: Cards(suit='spades', rank='7')

In [7]: spade_7.suit
Out[7]: 'spades'
In [8]: spade_7.rank
Out[8]: '7'

# 同样支持坐标索引
In [9]: spade_7[0]
Out[9]: 'spades'

如以上例子所示,使用namedtuple创建的卡牌对象,可读性明显高于原始的tuple,通过属性和值,spade_7这张牌的花色是黑桃,值是7.

2. 高效插入和删除的双端队列-deque

使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。

deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈。deque除了支持和list同样功能的append和extend,还支持左端插入appendleft,extendleft。以及左侧弹出popleft

from collections import deque

In [1]: dq = deque([1,2,3])

In [2]: dq
Out[2]: deque([1, 2, 3])

In [3]: dq.extend([4,5,6])
In [4]: dq.appendleft(-1)
In [5]: dq
Out[5]: deque([-1, 1, 2, 3, 4, 5, 6])

In [6]: dq.popleft()
Out[6]: -1

2.1 maxlen和rotate

deque 可以指定maxlen来设置队列深度,超出深度的数据会被丢弃

In [7]: dq = deque([1,2,3,4,5,6],maxlen=4)

In [8]: dq
Out[8]: deque([3, 4, 5, 6])

In [9]: dq.append(7)
In [10]: dq
Out[10]: deque([4, 5, 6, 7])

In [11]: dq.appendleft(0)
In [12]: dq
Out[12]: deque([0, 4, 5, 6])

# 使用rotate,将数据向后滚动, n可以指定滚动的距离
In [13]: dq.rotate()
In [14]: dq
Out[14]: deque([5, 6, 0, 4])

In [15]: dq.rotate(2)
In [16]: dq
Out[16]: deque([4, 5, 6, 0])

2.2 使用deque实现栈和队列

class Stack:
    def __init__(self, data, depth):
        self.stack = deque(data, maxlen=depth)

    def push(self, v):
        self.stack.append(v)

    def pop(self):
        self.stack.pop()
class Queue:
    def __init__(self, data, depth):
        self.stack = deque(data, maxlen=depth)

    def push(self, v):
        self.stack.appendleft(v)

    def pop(self):
        self.stack.pop()

2.3 queue和list的性能对比

测试脚本

from time import perf_counter
from collections import deque

n = 100000

start = perf_counter()
lst = []
for i in range(10): 
    lst.extend(range(n))
    now = perf_counter()
    print(f'extend {i} :', now - start)
    start = now

start = perf_counter()
dq = deque()
for i in range(10): 
    dq.extend(range(n))
    now = perf_counter()
    print(f'extend {i} :', now - start)
    start = now
次数n=10万n=100万n=1000万
listdequelistdequelistdeque
10.000160.000240.012670.01990.1350.18206
20.000990.002060.018680.019640.152350.18039
30.000430.002940.02080.01980.170420.18593
40.000400.002980.025120.019140.210750.19321
50.000370.00320.022680.019020.21910.18765
60.000300.002040.02456        0.019330.251370.21404
70.000480.002090.024640.019870.294510.18301
80.000460.002450.025770.021120.261840.17619
90.000330.002310.013280.019970.127870.179
100.000580.002830.031140.02040.329560.18637

从图中可以看出,随着数据的增大,list的extend的时间逐渐增大, deque的extend的时间相对平稳。当数据达到1000万级时,deque的性能优势才明显强于list。日常工作中少量的数据时,二者性能差距不大。

3.总结

① namedtuple 可以像访问对象的属性一样获取元组中的数据,提高代码的可读性。

② deque 提供左端的插入和弹出,100万级别的数据对比list的性能提升并不明显. 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: collections模块Python标准库的一个模块,提供了许多有用的数据类型。其包括: - deque: 双端队列 - Counter: 计数器 - OrderedDict: 有序字典 - defaultdict: 默认字典 - namedtuple: 命名元组 - ChainMap: 链接多个字典 使用这些类型可以更方便地进行数据操作和处理。 ### 回答2: collectionsPython标准库的一个模块,提供了许多有用的容器数据类型。这些数据类型是基于内置的数据类型(如字典,列表和集合等)的实现,以提供更多的功能和灵活性。 collections模块最常用的数据类型是:Counter、defaultdict、OrderedDict和namedtuple。 Counter是一个字典的子类,用于计算可哈希对象的出现次数。它可以接受任何可哈希对象的序列作为输入,并返回一个字典,其包含每个对象作为键和其出现次数作为值。 defaultdict是一个字典的子类,它可以接受一个工厂函数作为参数。当访问不存在的键时,默认会返回该工厂函数的返回值,而不是抛出KeyError异常。这对于处理缺失键的情况非常有用。 OrderedDict是一个有序的字典,它以插入顺序来维护元素的顺序。与普通的字典不同,OrderedDict可以记住元素的添加顺序,从而实现按照插入顺序进行遍历。 namedtuple是一个工厂函数,用于创建具有命名字段的元组子类。它允许我们为元组的每个字段指定一个名称,从而增加了元组的可读性和代码的可维护性。 除了上述常用的数据类型外,collections模块还提供了其他一些有用的类,如deque双端队列)、ChainMap(合并多个字典)、UserDict(方便地创建字典的一种方式)等。 总而言之,collections模块扩展了Python内置的容器数据类型,提供了更多方便、灵活和高效的数据结构,使我们在处理数据时更加方便和高效。它是每个Python程序员都应该熟悉和掌握的重要模块之一。 ### 回答3: collections模块Python标准库的一个模块,提供了一些常用的数据类型和工具,用于扩展内置的数据类型,提供方便的数据结构和算法。 collections模块最常用的数据类型是容器类型,包括:Counter、defaultdict、deque、OrderedDict和namedtuple。 1. Counter:用于计数元素出现的次数,并以字典的形式返回计数结果。它可以用于快速计数列表、字符串或任何可迭代对象的元素。 2. defaultdict:是内置字典类(dict)的一个子类,它通过传入一个默认值工厂函数,当键不存在时返回该默认值。这对于需要设置默认值的字典非常有用。 3. deque双端队列,可以快速在两端进行插入和删除操作,比内置的list类型更高效。 4. OrderedDict:有序字典,它会根据元素的插入顺序保持顺序,与普通字典不同,遍历时返回的键值对按照插入顺序排列。 5. namedtuple命名元组,是一个生成类的工厂函数,用于创建具有字段名称的元组。它可以通过字段名称访问元组的元素,提高了程序的可读性。 除了这些常用的数据类型,collections模块还提供了一些其他的工具函数,用于处理迭代器、排序和计数等操作。 总之,collections模块Python开发者提供了一些有用的数据类型和工具,可以简化常见的数据操作,提高开发效率。无论是在处理复杂数据结构还是简单计数,使用collections模块可以更方便地进行操作和处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值