利用 in 关键字使你的数据结构更友好

最近我突然想到: 在Python中,如果有一个支持使用“in”关键字的Tree对象Tree()会不会很方便呢?这样,我就可以简单地这样做: tree = Tree.from_list([1,2,3,4,5]) ... if val in tree: ... 好消息是,实际上我们是可以做到的!为了使类Tree与“in”方法兼容,我们需要实现__iter__方法。这个方法应该递归返回其子节点,使我们能够遍历整个树。 class Tree: def __init__(self, val, left=None, right=None): self.val = val self.left = left self.right = right def __iter__(self): if self.left: # 可以使用“yield from”来委托迭代给另一个可迭代对象。 yield from self.left yield self.val if self.right: yield from self.right 现在,您可以执行条件检查了! tree = Tree(6, left=Tree(4, left=Tree(2), right=Tree(5)), right=Tree(8)) if 5 in tree: print("Yes!") 如果不用 in, 我们可能需要做一个find方法: if tree.find(5): print("Yes!") 我相信无论哪种方法都很好看懂。使用“in”关键字的好处在于它利用了内置的关键字。

March 10, 2024

Python的多线程模块

最近我在复习并发编程相关的知识,由于日常工作我主要使用 Python, 我打算通过阅读和动手实践里面的模块来学习。 关于线程的原理和实现、线程同步问题我就不作介绍了。此类的参考书籍、文章、教学视频网上有很多。我在这里主要是列举 Python 标准库中提供的模块,以及它们的用法。如果你不了解线程、没有听说过生产者消费者模型,本文可能读起来有些吃力。 Lock Python 提供的,最简单的同步方法就是使用锁了。我们一起看看下面这个例子,两个线程一起做算术题: import threading import time count = 0 def counter(): global count while True: print(f'{count} + 1 = {count + 1}') count += 1 threads = [] for i in range(2): t = threading.Thread(target=counter) threads.append(t) t.start() for i in range(2): threads[i].join() 这个例子中,一种打印输出的情况是: 0 + 1 = 1 1 + 1 = 2 2 + 1 = 3 2 + 1 = 3 4 + 1 = 5 4 + 1 = 5 6 + 1 = 7 6 + 1 = 7 8 + 1 = 9 8 + 1 = 9 可以看到打印结果有重复的。这是由于两个线程同时访问 count 并且都执行了 count + 1。例如,两个线程同时获得 count=5,同时执行 5 + 1 = 6,就会出现重复的情况。...

December 10, 2022