有没有一种方法可以提示以二进制方式搜索元组?

时间:2019-10-04 16:16:24

标签: python python-3.x python-typing

您能告诉Python字符串列表是经过排序的并且可以用二进制方式进行搜索吗?

假设您有一个类似的字符串元组:

from typing import Tuple
words: Tuple[str] = ("alphabet", "bike", "car", "house", "word")

首先,我是否输入了正确的提示? 其次,有没有办法告诉python这个元组可以用二进制方式搜索(因为它已排序),还是没有必要?

2 个答案:

答案 0 :(得分:0)

类型注释应为Tuple[t1, t2, ...],其中t1, t2...是对应的元组值的类型。您键入的方式提示了元组,这意味着它是一个包含单个字符串项的元组。

创建类型提示系统是为了将类似静态的声明引入python,因此需要注意两点

    如果您的元组包含2-3个项目(例如,Tuple[number, number]表示2D点),则注释元组就很有意义。您拥有的是一个集合,最好标注为Iterable[str]
  • 无法表示集合已排序,因为 type 注释仅注释 type ,而与集合是否已排序无关。

答案 1 :(得分:0)

您不能说元组可以使用类型提示进行二进制搜索。但是,您可以编写一个装饰器来包装您的函数,并强制对所有输入元组进行排序。如果您有许多需要排序元组作为输入的函数,那么这可能是一个好主意。它不会修改元组(它不能-元组不可变)


def is_sorted(t):
    """ Returns true if the tuple, t, is sorted """
    return sorted(list(t)) == list(t)

def enforce_sort(func):
    def inner(*args, **kwargs):
        new_args = [None]*len(args) # Since args is a tuple, we can't modify it
        for n, arg in enumerate(args):
            new_args[n] = arg 
            if isinstance(arg, tuple):
                ## Do you want to sort it?
                new_args[n] = tuple(sorted(arg))
                ## Or do you wait to raise an exception if its not sorted?
                # if not is_sorted(arg):
                #     raise ValueError("Input tuple must be sorted")
        for k, v in kwargs.items():
            if isinstance(v, tuple):
                ## Do you want to sort it?
                kwargs[k] = tuple(sorted(v))
                ## Or do you want to raise an exception if its not sorted?
                # if not is_sorted(v):
                #    raise ValueError("Input tuple must be sorted")
        return func(*new_args, **kwargs)
    return inner

@enforce_sort
def show_twoples(t1, t2):
    """ prints two tuples, t1 and t2 """
    print(f"t1: {t1}")
    print(f"t2: {t2}")

a = (1,2,3,4,5) # Sorted
b = (9,8,6,4,2) # Not sorted
c = [1,2,6,2,3] # Not sorted, but not a tuple so it won't be affected
print(f"\nOriginal: t1 = {a}, t2 = {b}")
show_twoples(a, b)
print(f"\nOriginal: t1 = {b}, t2 = {a}")
show_twoples(b, a)
print(f"\nOriginal: t1 = {a} t2 = {c}")
show_twoples(a, c)
print(f"\nOriginal: t1 = {c}, t2 = {b}")
show_twoples(t1 = c, t2 = b)

输出:

Original: t1 = (1, 2, 3, 4, 5), t2 = (9, 8, 6, 4, 2)
t1: (1, 2, 3, 4, 5)
t2: (2, 4, 6, 8, 9)

Original: t1 = (9, 8, 6, 4, 2), t2 = (1, 2, 3, 4, 5)
t1: (2, 4, 6, 8, 9)
t2: (1, 2, 3, 4, 5)

Original: t1 = (1, 2, 3, 4, 5) t2 = [1, 2, 6, 2, 3]
t1: (1, 2, 3, 4, 5)
t2: [1, 2, 6, 2, 3]

Original: t1 = [1, 2, 6, 2, 3], t2 = (9, 8, 6, 4, 2)
t1: [1, 2, 6, 2, 3]
t2: (2, 4, 6, 8, 9)

根据需要,您可以在装饰器中自动对元组进行排序(这是它现在正在做的事情),或者如果元组未排序,则可以引发异常(通过切换注释掉的部分)。 / p>