【雕爷学编程】MicroPython手册之内置模块 deque

在这里插入图片描述

MicroPython是为了在嵌入式系统中运行Python 3编程语言而设计的轻量级版本解释器。与常规Python相比,MicroPython解释器体积小(仅100KB左右),通过编译成二进制Executable文件运行,执行效率较高。它使用了轻量级的垃圾回收机制并移除了大部分Python标准库,以适应资源限制的微控制器。

MicroPython主要特点包括:
1、语法和功能与标准Python兼容,易学易用。支持Python大多数核心语法。
2、对硬件直接访问和控制,像Arduino一样控制GPIO、I2C、SPI等。
3、强大的模块系统,提供文件系统、网络、图形界面等功能。
4、支持交叉编译生成高效的原生代码,速度比解释器快10-100倍。
5、代码量少,内存占用小,适合运行在MCU和内存小的开发板上。
6、开源许可,免费使用。Shell交互环境为开发测试提供便利。
7、内置I/O驱动支持大量微控制器平台,如ESP8266、ESP32、STM32、micro:bit、掌控板和PyBoard等。有活跃的社区。

MicroPython的应用场景包括:
1、为嵌入式产品快速构建原型和用户交互。
2、制作一些小型的可 programmable 硬件项目。
3、作为教育工具,帮助初学者学习Python和物联网编程。
4、构建智能设备固件,实现高级控制和云连接。
5、各种微控制器应用如物联网、嵌入式智能、机器人等。

使用MicroPython需要注意:
1、内存和Flash空间有限。
2、解释执行效率不如C语言。
3、部分库函数与标准版有差异。
4、针对平台优化语法,订正与标准Python的差异。
5、合理使用内存资源,避免频繁分配大内存块。
6、利用原生代码提升速度关键部位的性能。
7、适当使用抽象来封装底层硬件操作。

总体来说,MicroPython让Python进入了微控制器领域,是一项重要的创新,既降低了编程门槛,又提供了良好的硬件控制能力。非常适合各类物联网和智能硬件的开发。

在这里插入图片描述
MicroPython的内置模块deque是一个双端队列,它可以在两端高效地添加和删除元素,类似于一个列表,但是比列表更适合用作队列和栈的数据结构。deque的主要特点有:

1、deque是可迭代的,支持bool和len操作。
2、deque可以指定一个最大长度,当达到最大长度时,再添加新元素会导致另一端的元素被丢弃。
3、deque可以选择是否开启溢出检查,当开启时,如果没有空间添加新元素,会抛出IndexError异常。
4、deque支持append和popleft方法,在右端添加和在左端删除元素。
5、deque不支持比较不同类型码的deque,也不支持删除、切片和查找元素的操作。

deque的应用场景有:

1、当需要一个先进先出(FIFO)或后进先出(LIFO)的数据结构时,可以使用deque作为队列或栈。
2、当需要在两端频繁地添加或删除元素时,可以使用deque,因为它比列表更高效。
3、当需要限制容器的大小时,可以使用deque,因为它可以自动丢弃多余的元素。

deque的注意事项有:

1、deque是MicroPython的内置模块,不是CPython的标准库模块,所以它只实现了CPython模块的一个子集。
2、deque不支持一些列表常用的操作,如索引、切片、排序等,所以如果需要这些操作,可能需要转换成列表或使用其他方法。
3、deque不是线程安全的,所以如果在多线程环境中使用deque,可能需要加锁或使用其他同步机制。

下面给出MicroPython的内置模块deque几个实际运用程序案例:

案例1:使用deque实现一个简单的循环缓冲区,用于存储最近收到的数据包::

from collections import deque

# 创建一个最大长度为10的deque
buffer = deque((), 10, 1)

# 模拟收到数据包
def receive_packet():
    # 返回一个随机长度的字节串
    from urandom import randint
    return bytes(randint(0, 255) for _ in range(randint(1, 10)))

# 循环接收数据包并存入缓冲区
while True:
    packet = receive_packet()
    buffer.append(packet)
    print("Received:", packet)
    print("Buffer:", buffer)

案例2:使用deque实现一个简单的撤销功能,用于记录用户输入的历史记录::

from collections import deque

# 创建一个最大长度为5的deque
history = deque((), 5, 1)

# 模拟用户输入
def user_input():
    # 返回用户输入的字符串
    return input("Enter something: ")

# 循环获取用户输入并存入历史记录
while True:
    text = user_input()
    if text == "undo":
        # 如果用户输入undo,则从历史记录中弹出最近一次输入
        if history:
            print("Undo:", history.popleft())
        else:
            print("Nothing to undo")
    else:
        # 否则将用户输入添加到历史记录中
        history.appendleft(text)
        print("History:", history)

案例3:使用deque实现一个简单的任务调度器,用于按顺序执行不同优先级的任务::

from collections import deque

# 创建三个不同优先级的任务队列
high_priority = deque()
medium_priority = deque()
low_priority = deque()

# 模拟生成任务
def generate_task():
    # 返回一个随机优先级和内容的任务
    from urandom import choice, randint
    priority = choice(["high", "medium", "low"])
    content = "Task " + str(randint(1, 100))
    return (priority, content)

# 循环生成任务并添加到相应的队列中
while True:
    task = generate_task()
    priority, content = task
    if priority == "high":
        high_priority.append(content)
    elif priority == "medium":
        medium_priority.append(content)
    else:
        low_priority.append(content)
    print("Generated:", task)

    # 按优先级从高到低执行任务
    if high_priority:
        print("Executed:", high_priority.popleft())
    elif medium_priority:
        print("Executed:", medium_priority.popleft())
    elif low_priority:
        print("Executed:", low_priority.popleft())

案例4:循环队列:

from collections import deque

# 创建一个循环队列
queue = deque(maxlen=3)

# 向队列中添加元素
queue.append(1)
queue.append(2)
queue.append(3)

# 队列已满,添加新元素将删除最旧的元素
queue.append(4)

# 遍历队列中的元素
for item in queue:
    print(item)

在这个示例中,我们使用collections模块的deque类创建了一个长度为3的循环队列。通过设置maxlen参数为3,我们限制了队列的最大长度。当队列已满时,添加新元素将会删除最旧的元素。在这里,我们向队列中添加了4个元素,其中最旧的元素1已被删除。通过遍历队列,我们可以逐个访问队列中的元素。输出结果为:

2
3
4

案例5:双端队列操作::

from collections import deque

# 创建一个双端队列
deque_list = deque([1, 2, 3, 4, 5])

# 在队列的左侧添加元素
deque_list.appendleft(0)

# 在队列的右侧添加元素
deque_list.append(6)

# 从队列的左侧弹出元素
left_item = deque_list.popleft()

# 从队列的右侧弹出元素
right_item = deque_list.pop()

# 输出最终的队列
print(deque_list)

在这个示例中,我们使用collections模块的deque类创建了一个双端队列。通过appendleft()函数,我们可以在队列的左侧添加元素,而使用append()函数可以在队列的右侧添加元素。通过popleft()函数,我们可以从队列的左侧弹出元素,而使用pop()函数可以从队列的右侧弹出元素。在这里,我们对双端队列执行了一系列操作,并打印最终的队列。输出结果为:

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

案例6:队列旋转::

from collections import deque

# 创建一个队列
queue = deque([1, 2, 3, 4, 5])

# 将队列向右旋转2个位置
queue.rotate(2)

# 输出旋转后的队列
print(queue)

在这个示例中,我们使用collections模块的deque类创建了一个队列。通过使用rotate()函数,我们可以将队列中的元素向右旋转指定的位置数。在这里,我们将队列向右旋转2个位置,即最右侧的2个元素会移动到最左侧。输出结果为:

deque([4, 5, 1, 2, 3])

案例7:使用 deque 实现循环缓冲区

from collections import deque

# 创建一个循环缓冲区,最大容量为 3
buffer = deque(maxlen=3)

# 向缓冲区中添加数据
buffer.append(1)
buffer.append(2)
buffer.append(3)

# 缓冲区已满,继续添加数据将会移除最早的数据
buffer.append(4)

# 访问缓冲区中的数据
data = buffer[0]

# 打印结果
print("缓冲区中的数据:", buffer)
print("第一个数据:", data)

在这个例子中,我们使用 collections 模块中的 deque 类创建了一个循环缓冲区 buffer,其最大容量为 3。我们连续向缓冲区中添加了 4 个数据。由于缓冲区已满,添加新数据时会自动移除最早的数据。我们通过索引访问缓冲区中的数据,这里我们获取了第一个数据,并打印出结果。

案例8:使用 deque 实现先进先出队:

from collections import deque

# 创建一个先进先出(FIFO)队列
queue = deque()

# 向队列中添加元素
queue.append(1)
queue.append(2)
queue.append(3)

# 从队列中获取元素
item = queue.popleft()

# 打印结果
print("队列中的元素:", queue)
print("出队的元素:", item)

在这个例子中,我们使用 collections 模块中的 deque 类创建了一个先进先出(FIFO)队列 queue。我们向队列中添加了 3 个元素,然后使用 popleft() 方法从队列的左侧获取并移除元素,模拟出队操作。最后,我们打印了队列中的元素和出队的元素。

案例9:使用 deque 实现最近最少使用(LRU)缓存
:

from collections import deque

class LRUCache:
    def __init__(self, capacity):
        self.capacity = capacity
        self.cache = deque()

    def get(self, key):
        if key in self.cache:
            self.cache.remove(key)
            self.cache.append(key)
            return True
        else:
            return False

    def put(self, key):
        if key in self.cache:
            self.cache.remove(key)
        elif len(self.cache) >= self.capacity:
            self.cache.popleft()
        self.cache.append(key)

# 创建一个容量为 3 的最近最少使用(LRU)缓存
cache = LRUCache(3)

# 模拟缓存操作
cache.put("A")
cache.put("B")
cache.put("C")
cache.get("A")
cache.put("D")

# 打印缓存中的数据
print("缓存中的数据:", cache.cache)

在这个例子中,我们使用 collections 模块中的 deque 类和自定义的 LRUCache 类实现了一个最近最少使用(LRU)缓存。我们通过 put() 方法添加数据到缓存中,如果缓存已满,则移除最早访问的数据;通过 get() 方法从缓存中获取数据,如果数据存在,则将其移到缓存的尾部,表示最近访问。最后,我们打印了缓存中的数据。

这些示例展示了在 MicroPython 中使用 deque 类的实际应用。deque 可以用于实现循环缓冲区、先进先出队列以及最近最少使用(LRU)缓存等数据结构和算法。通过利用 deque,你可以更灵活地处理特定的数据存储和操作需求。

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

驴友花雕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值