Эффективное сопоставление слов с отсортированным словарем в Python

С одной стороны, у меня есть словарь существительных в алфавитном порядке (#7000).

aardvark
abacus
abbey
abbreviation
abdomen
ability
abnormal

С другой стороны у меня есть набор слов (#1E6)

['Hello', 'airport', 'really', 'sorry', 'to', 'hear', 'this'...]

Каков наиболее эффективный способ узнать, присутствует ли слово в словаре и индексе?

Я мог бы просто использовать списки/массивы и сравнивать строки, но это не использует алфавитную сортировку словаря.

Быстрый поиск в отсортированном массиве/списке -> бинарный поиск со сложностью log(n)

h4z3 27.05.2019 14:16

Вы можете использовать наборы, словари или бинарный поиск.

mkrieger1 27.05.2019 14:17

Вы можете загрузить словарный запас в виде словаря. Значение может быть индексом. Поскольку время поиска в словаре составляет O(1), я думаю, что это может быть весьма полезным. Я имею в виду все же, загрузка из файла займет некоторое время, но это займет время в любом случае, если вы это сделаете.

Mansur 27.05.2019 14:18

@MensurQulami у меня тоже работает

eddie 27.05.2019 14:57
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
4
207
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете использовать делить пополам, чтобы воспользоваться отсортированным словарем:

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.

Хорошее и эффективное решение, я соглашусь, если не появится ничего лучше

eddie 27.05.2019 14:56

На самом деле словарь проще

eddie 27.05.2019 15:15

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

AdamGold 27.05.2019 16:00

Если в словаре есть уникальные записи (как я и ожидал), вы можете использовать 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.

AdamGold 27.05.2019 15:02

С каких это пор наборы имеют индексы?

Işık Kaplan 27.05.2019 15:03

Правильно, забыл про индекс! Виноват.

AdamGold 27.05.2019 15:04

Другие вопросы по теме