Во время моей недавней работы над математической задачей на Python я столкнулся с некоторой путаницей относительно поведения функции bisect.bisect_left из библиотеки bisect. Эта путаница возникла из-за ее сходства с другой функцией библиотеки, а именно bisect.insort_left.
В моем конкретном случае я использовал специальную функцию клавиши, например bisect.insort_left(my_list, my_item, key=my_key), которая вела себя так, как ожидалось. Эта функция определила соответствующий индекс для my_item в my_list, используя указанный ключ, и вставила его соответствующим образом.
Однако при попытке аналогичной операции с bisect.bisect_left(my_list, my_item, key=my_key) я столкнулся с неожиданной ошибкой TypeError: «другой аргумент должен быть экземпляром K». В этом сообщении об ошибке не было ясности относительно основной проблемы.
Изучив исходный код bisect, я обнаружил правильный шаблон использования, как указано в строке 71 исходного кода. Стало очевидно, что правильное использование предполагает вызов функции ключа с элементом в качестве аргумента, например: bisect.bisect_left(my_list, my_key(my_item), key=my_key).
Мне интересно узнать дизайнерское решение, лежащее в основе этого требования. Почему необходимо вызывать my_key(my_item) при использовании bisect.bisect_left по сравнению с более простым использованием bisect.insort_left?
Судя по обсуждению в системе отслеживания ошибок проблемы, которая в конечном итоге привела к добавлению этой функции, кажется, что семейство функций bisect.bisect было разработано так, чтобы не вызывать клавишу x и вместо этого ожидать, что желаемый ключ будет передан как x , поскольку функции bisect обычно вызываются неоднократно. insort, с другой стороны, требуется как вставляемый элемент, так и ключ, используемый для вычисления точки вставки, поэтому он будет вызывать key(x) внутри.






Допустим, элементы списка содержат много данных. Каждый элемент может быть e. г. диктат
{
'id': 12,
'firstname': 'foo',
'lastname': 'bar',
'address': ...,
'phone': ...
...
}
Эти элементы сортируются в списке по id с соответствующей ключевой функцией, например lambda item: item['id'].
Если вы хотите найти элемент с bisect_left, не обязательно предоставлять весь элемент со всеми его данными, но идентификатора должно быть достаточно.
В документации это упоминается немного загадочно:
Для поддержки поиска по сложным записям функция ключа не применяется. до значения х.
Если вы хотите вставить элемент с insort_left, конечно, вам необходимо предоставить полный элемент со всеми данными.
вы проверили документы? docs.python.org/3/library/bisect.html