Я хочу использовать что-то вроде difflib.get_close_matches
, но вместо наиболее похожие строки, я хотел бы получить индексы (т.е. позицию в списке).
Индексы списка более гибкие, потому что можно связать индекс с другими структурами данных (связанными с совпадающей строкой).
Например, вместо:
>>> words = ['hello', 'Hallo', 'hi', 'house', 'key', 'screen', 'hallo', 'question', 'format']
>>> difflib.get_close_matches('Hello', words)
['hello', 'hallo', 'Hallo']
Мне бы хотелось:
>>> difflib.get_close_matches('Hello', words)
[0, 1, 6]
Кажется, не существует параметра для получения этого результата, есть ли альтернатива difflib.get_close_matches()
, которая возвращает индексы?
Мое исследование альтернативы
Я знаю, что могу использовать difflib.SequenceMatcher
, а затем сравнивать строки один к одному с ratio
(или quick_ratio
). Однако я боюсь, что это будет очень неэффективно, потому что:
Мне пришлось бы создать тысячи объектов SequenceMatcher и сравнить их (я ожидаю, что
get_close_matches
избегает использования класса):EDIT: неверно. Я проверил исходный код
get_close_matches
, он действительно используетSequenceMatcher
.нет отсечки (я предполагаю, что есть оптимизация, которая позволяет избежать расчета коэффициента для всей строки)
EDIT: частично неверно. Код
get_close_matches
не содержит серьезных оптимизаций, за исключением использованияreal_quick_ratio
,quick_ratio
иratio
вместе. В любом случае я могу легко скопировать оптимизацию в свою функцию. Также я не учел, что у SequenceMatcher есть методы для установки последовательностей:set_seq1
,set_seq2
, так что по крайней мере мне не придется каждый раз создавать объект.насколько я понимаю, все библиотеки Python скомпилированы на C, и это повысит производительность.
EDIT: я совершенно уверен, что это так. Функция находится в папке cpython.
EDIT: существует небольшая разница (значение p равно 0,030198) между выполнением непосредственно из difflib и копированием функция в файле mydifflib.py.
ipdb> timeit.repeat("gcm('hello', _vals)", setup="from difflib import get_close_matches as gcm; _vals=['hello', 'Hallo', 'hi', 'house', 'key', 'screen', 'hallo', 'question', 'format']", number=100000, repeat=10) [13.230449825001415, 13.126462900007027, 12.965455356999882, 12.955717618009658, 13.066136312991148, 12.935014379996574, 13.082025538009475, 12.943519036009093, 13.149949093989562, 12.970130036002956] ipdb> timeit.repeat("gcm('hello', _vals)", setup="from mydifflib import get_close_matches as gcm; _vals=['hello', 'Hallo', 'hi', 'house', 'key', 'screen', 'hallo', 'question', 'format']", number=100000, repeat=10) [13.363269686000422, 13.087718107010005, 13.112324478992377, 13.358293497993145, 13.283965317998081, 13.056695280989516, 13.021098569995956, 13.04310674899898, 13.024205000008806, 13.152750282009947]
Тем не менее, это не так плохо, как я ожидал, я думаю, что продолжу, если кто-нибудь не знает другую библиотеку или альтернативу.