Есть ли способ напечатать подсказку, что кортеж можно искать в двоичном виде? - PullRequest
0 голосов
/ 04 октября 2019

Можете ли вы сказать Python, что список строк отсортирован и его можно искать в двоичном виде?

Скажем, у вас есть набор строк, например:

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

Во-первых,я правильно намекал на это? Во-вторых, есть ли способ сообщить Python, что этот кортеж можно искать в двоичном виде (потому что он отсортирован) или он не нужен?

Ответы [ 2 ]

0 голосов
/ 04 октября 2019

Нельзя сказать, что кортеж доступен для двоичного поиска с использованием подсказок типа. Однако вы можете написать декоратор, чтобы обернуть ваши функции так, чтобы все входные кортежи были отсортированы. Это, вероятно, хорошая идея, если у вас есть много функций, которые требуют отсортированных кортежей в качестве входных данных. Он НЕ изменяет кортежи (он не может - кортежи не являются изменяемыми)


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)

В зависимости от того, что вы хотите, вы можете автоматически сортировать кортежив декораторе (что он и делает сейчас), или вы можете вызвать исключение, если кортеж не отсортирован (путем переключения, какая часть закомментирована).

0 голосов
/ 04 октября 2019

Тип аннотации должен быть Tuple[t1, t2, ...], где t1, t2... - это типы для соответствующих значений кортежа. То, как вы ввели, подсказало ваш кортеж, это означает, что это кортеж с одним строковым элементом.

Система подсказок типов создана для переноса статических объявлений в python, поэтому две вещи, на которые следует обратить внимание

  • , аннотируют кортежи, если у вас есть кортежи из 2-3 элементов (например, Tuple[number, number] для обозначения 2D-точки). То, что у вас есть, является коллекцией, и ее лучше аннотировать как Iterable[str].
  • Нет способа обозначить, что коллекция отсортирована, потому что type аннотация аннотирует только type , который не зависит от того, отсортирована ли коллекция.
...