当前位置:嗨网首页>书籍在线阅读

06-通用示例

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

2.1.4 通用示例

函数 linear_contains()binary_contains() 可以广泛应用于几乎所有Python序列。以下通用版本与之前的版本几乎完全相同,只不过有一些名称和类型提示信息有一些变化。具体代码如代码清单2-9所示。

注意  代码清单2-9中有很多导入的类型。本章后续有很多通用搜索算法都将复用generic_search.py文件,这样就可以避免导入的麻烦。

注意   在往下继续之前,需要用 pip install typing_extensionspip3 install typing_extensions 安装 typing_extensions 模块,具体命令取决于Python解释器的配置方式。这里需要通过该模块获得 Protocol 类型,Python后续版本的标准库中将会包含这个类型(PEP 544已有明确说明)。因此在Python的后续版本中,应该不需要再导入 typing_extensions 模块了,并且会用 from typing import Protocol 替换 from typing_extensions import Protocol

代码清单2-9 generic_search.py

from __future__ import annotations
from typing import TypeVar, Iterable, Sequence, Generic, List, Callable, Set, Deque, 
    Dict, Any, Optional
from typing_extensions import Protocol
from heapq import heappush, heappop
T = TypeVar('T')
def linear_contains(iterable: Iterable[T], key: T) -> bool:
    for item in iterable:
        if item == key:
            return True
    return False
C = TypeVar("C", bound="Comparable")
class Comparable(Protocol):
    def __eq__(self, other: Any) -> bool:
       ...
    def __lt__(self: C, other: C) -> bool:
       ...
    def __gt__(self: C, other: C) -> bool:
        return (not self < other) and self != other
    def __le__(self: C, other: C) -> bool:
        return self < other or self == other
    def __ge__(self: C, other: C) -> bool:
        return not self < other
def binary_contains(sequence: Sequence[C], key: C) -> bool:
    low: int = 0
    high: int = len(sequence) - 1
    while low <= high:  # while there is still a search space
        mid: int = (low + high) // 2
        if sequence[mid] < key:
            low = mid + 1
        elif sequence[mid] > key:
            high = mid - 1
        else:
            return True
    return False
if __name__ == "__main__":
    print(linear_contains([1, 5, 15, 15, 15, 15, 20], 5))  # True
    print(binary_contains(["a", "d", "e", "f", "z"], "f"))  # True
    print(binary_contains(["john", "mark", "ronald", "sarah"], "sheila"))  # False

现在可以尝试搜索其他类型的数据了。这些函数几乎可以复用于任何Python集合类型。这正是编写通用代码的威力。上述例子中唯一的遗憾之处就是为了满足Python类型提示的要求,必须以 Comparable 类的形式实现。 Comparable 是一种实现比较操作符(<、> =等)的类型。在后续的Python版本中,应该有一种更简洁的方式来为实现这些常见操作符的类型创建类型提示。