С одной стороны, у меня есть словарь существительных в алфавитном порядке (#7000).
aardvark
abacus
abbey
abbreviation
abdomen
ability
abnormal
С другой стороны у меня есть набор слов (#1E6)
['Hello', 'airport', 'really', 'sorry', 'to', 'hear', 'this'...]
Каков наиболее эффективный способ узнать, присутствует ли слово в словаре и индексе?
Я мог бы просто использовать списки/массивы и сравнивать строки, но это не использует алфавитную сортировку словаря.
Вы можете использовать наборы, словари или бинарный поиск.
Вы можете загрузить словарный запас в виде словаря. Значение может быть индексом. Поскольку время поиска в словаре составляет O(1), я думаю, что это может быть весьма полезным. Я имею в виду все же, загрузка из файла займет некоторое время, но это займет время в любом случае, если вы это сделаете.
@MensurQulami у меня тоже работает
Вы можете использовать делить пополам, чтобы воспользоваться отсортированным словарем:
In [1]: d = ["aardvark", "abacus", "abbey", "abbreviation"]
In [2]: w = ['Hello', 'airport', 'really', 'sorry', 'to', 'hear', 'this', "aardvark"]
In [3]: for wd in w:
...: try:
...: index = bisect.bisect_left(d, wd)
...: found = d[index]
...: if found == wd:
...: print(f"{wd} found at index {index}")
...: except IndexError:
...: pass
...:
aardvark found at index 0
Другим вариантом может быть использование словаря и поиск word in set
или dictionary.get(word)
для индекса. Вы можете прочитать мой ответ здесь для получения подробной информации о реализации dict
в CPython.
Хорошее и эффективное решение, я соглашусь, если не появится ничего лучше
На самом деле словарь проще
Вы можете использовать любой из них. Вы должны выполнить несколько тестов на ваших реальных данных, чтобы увидеть, какой из них быстрее, или просто выбрать тот, который вы предпочитаете.
Если в словаре есть уникальные записи (как я и ожидал), вы можете использовать dict. x in dict
возвращает true
, если x
является ключом в данном dict
и (при отсутствии коллизий хэшей) требует статического времени, так что это лучшее, что мы могли когда-либо получить. Стоит отметить, что худший случай O(n)
, но обычно он близок к лучшему. Подробности см. в вопросе это.
Чтобы получить dict с индексами в качестве значений, используйте эту строку:
newdict = dict((k, v) for k, v in enumerate(sortedlist))
[Обновлено:] Обратите внимание, что это не зависит от отсортированного списка или любого списка. Он будет работать для любых итераций, включая открытые файлы с одним словом в строке или string.split()...
Если вы хотите сохранить свою текущую структуру данных, вы можете использовать подтипы или докорацию, чтобы держать под капотом словарь, который обновляется и используется для такого рода поиска.
Как было сказано ранее:
>>> vocab = ['a', 'b', 'c']
>>> vocab_lookup = {k:v for v,k in enumerate(vocab)}
И теперь все, что вам нужно использовать, это dict.get
или просто dict[]
>>> 'a' in vocab_lookup
True
>>> 'd' in vocab_lookup
False
>>> vocab_lookup.get('a')
0
>>> vocab_lookup.get('d')
>>> # None
Нет необходимости создавать словарь. Вы также можете использовать set
.
С каких это пор наборы имеют индексы?
Правильно, забыл про индекс! Виноват.
Быстрый поиск в отсортированном массиве/списке -> бинарный поиск со сложностью log(n)