有没有一种方法可以键入可以以二进制方式搜索元组的提示?
Is there a way to type hint that a tuple can be searched in a binary way?
你能告诉Python一个字符串列表是排序的并且可以用二进制方式搜索吗?
假设你有一个这样的字符串元组:
from typing import Tuple
words: Tuple[str] = ("alphabet", "bike", "car", "house", "word")
首先,我输入的提示是否正确?
其次,有没有办法告诉python这个元组可以用二进制方式搜索(因为它是排序的)还是不需要的?
类型注释应为 Tuple[t1, t2, ...]
,其中 t1, t2...
是相应元组值的类型。您键入的方式暗示了您的元组,这意味着它是一个包含单个字符串项的元组。
创建类型提示系统是为了将类似静态的声明带入 python,所以有两点需要注意
如果您有 2-3 个项目的元组,- 注释元组就有意义(例如,
Tuple[number, number]
表示一个 2D 点)。您拥有的是一个集合,最好将其注释为 Iterable[str]
.
- 无法表示集合已排序,因为 type 注释仅注释 type,这与集合是否排序无关已排序。
你不能说元组是可以使用类型提示进行二进制搜索的。但是,您可以编写一个装饰器来包装您的函数,强制对所有输入元组进行排序。如果您有许多需要排序的元组作为输入的函数,这可能是个好主意。它不会修改元组(它不能——元组是不可变的)
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)
根据您的需要,您可以在装饰器中自动对元组进行排序(这就是它现在所做的),或者如果元组未排序则可以引发异常(通过切换注释掉的部分) .
你能告诉Python一个字符串列表是排序的并且可以用二进制方式搜索吗?
假设你有一个这样的字符串元组:
from typing import Tuple
words: Tuple[str] = ("alphabet", "bike", "car", "house", "word")
首先,我输入的提示是否正确? 其次,有没有办法告诉python这个元组可以用二进制方式搜索(因为它是排序的)还是不需要的?
类型注释应为 Tuple[t1, t2, ...]
,其中 t1, t2...
是相应元组值的类型。您键入的方式暗示了您的元组,这意味着它是一个包含单个字符串项的元组。
创建类型提示系统是为了将类似静态的声明带入 python,所以有两点需要注意
-
如果您有 2-3 个项目的元组,
- 注释元组就有意义(例如,
Tuple[number, number]
表示一个 2D 点)。您拥有的是一个集合,最好将其注释为Iterable[str]
. - 无法表示集合已排序,因为 type 注释仅注释 type,这与集合是否排序无关已排序。
你不能说元组是可以使用类型提示进行二进制搜索的。但是,您可以编写一个装饰器来包装您的函数,强制对所有输入元组进行排序。如果您有许多需要排序的元组作为输入的函数,这可能是个好主意。它不会修改元组(它不能——元组是不可变的)
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)
根据您的需要,您可以在装饰器中自动对元组进行排序(这就是它现在所做的),或者如果元组未排序则可以引发异常(通过切换注释掉的部分) .