#python #arrays #function #memory-management #nlp
Вопрос:
Я пытаюсь создать функцию, чтобы увидеть, появляются ли слова на определенном расстоянии друг от друга, мой код выглядит следующим образом:
file_cont = [['man', 'once', 'upon', 'time', 'love', 'princess'], ['python', 'code', 'cool', 'uses', 'java'], ['man', 'help', 'test', 'weird', 'love']] #words I want to measure 'distance' between dat = [{ind: val for val, ind in enumerate(el)} for el in file_cont] def myfunc(w1, w2, dist, dat): arr = [] for x in dat: i1 = x.get(w1) i2 = x.get(w2) if (i1 is not None) and (i2 is not None) and (i2 - i1 lt;= dist ): arr.append(list(x.keys())[i1:i2 1]) return arr
Это работает в данном случае,
myfunc(«человек», «Любовь»,4, DAT-файла) возвращает [[‘человек’, ‘как только’, ‘по’, ‘Время’, ‘любить’], [‘человек’, ‘помощь’, ‘тест’, ‘странно’, ‘любить’]] , который является то, что я хочу
Проблема, с которой я сталкиваюсь, заключается в том, что когда я использую гораздо больший набор данных (элементы file_cont становятся тысячами слов), он выдает нечетные результаты
Например, я знаю, что слова «джон» и «снег» появляются вместе по крайней мере в одном экземпляре в одном из элементов file_cont
Когда я выполняю свою функцию(«джон»,»сноу»,6,дата), я получаю:
[[], [], [‘замок’, ‘палата’], [], [], []]
что-то совершенно вырванное из контекста, в нем не упоминается «джон» или «сноу»
В чем здесь проблема и как бы я ее решил исправить?
Комментарии:
1. Мне приходят на ум две вещи: во-первых, вы упомянули, что проблема возникает только при использовании большего набора данных. Как вы используете этот набор данных? Вы читаете текстовый файл и разбиваете его на список? Проблема может быть вызвана тем, как вы читаете свои данные. В противном случае вы упоминаете случай
"jon"
и."snow"
Возможно, вам следует убедиться, что вы ищете слова без учета регистра, например, используяs.lower()
гдеs
находится строка?2. @bglbrt Я записал слова в нижнем регистре и все еще испытываю ту же проблему
3. @bglbrt это также те же данные из [[‘string1’, ‘string2’], [‘string3’, ‘string4’, ‘string5’]] только длиннее
4. Я добавил ответ, исследующий дальнейшую проблему, которая, как я полагаю, связана с тем фактом, что в ваших новых данных может быть несколько вхождений одних и тех же слов.
5. @bglbrt код работает для более длинных больших списков, но, похоже, все еще не работает для списка длинных списков, т. е. [ [ ‘word1’,…., ‘word1000’], [‘word3’,….. ‘word5000’], [‘word4’,…. ‘word400’]] даже когда слова, между которыми я хочу найти расстояние, находятся в одном списке (к чему я и стремлюсь)
Ответ №1:
Проблема заключается в том, что ваш текст может содержать несколько вхождений одного и того же слова, которые вы обычно наблюдаете с большими выдержками.
Вот минимальный рабочий пример, показывающий, как функция может выйти из строя:
new_file = [['man', 'once', 'man', 'time', 'love', 'once']] data = [{ind: val for val, ind in enumerate(el)} for el in new_file] def myfunc(w1, w2, dist, dat): arr = [] for x in dat: i1 = x.get(w1) i2 = x.get(w2) if (i1 is not None) and (i2 is not None) and (i2 - i1 lt;= dist ): arr.append(list(x.keys())[i1:i2 1]) return arr myfunc("man", "love", 4, data) # gt; [['time', 'love']]
Обратите внимание, что здесь ваш словарь будет выглядеть следующим образом:
# gt; [{'man': 2, 'once': 5, 'time': 3, 'love': 4}]
Это связано с тем, что при создании словаря каждое новое вхождение слова будет заменять его ключ в словаре новым наблюдаемым (более высоким) индексом. Таким образом, функция myfunc
не работает, так как ключи в словаре больше не соответствуют индексам слов в отрывке.
Способ достичь того, что вы хотите сделать, может быть (например):
data = ['man', 'once', 'upon', 'man', 'time', 'love', 'princess', 'man'] w1 = 'man' w2 = 'love' dist = 3 def new_func(w1, w2, dist, data): w1_indices = [i for i, x in enumerate(data) if x == w1] w2_indices = [i for i, x in enumerate(data) if x == w2] for i in w1_indices: for j in w2_indices: if abs(i-j) lt; dist: print(data[min(i, j):max(i, j) 1]) new_func(w1, w2, dist, data) # gt; ['man', 'time', 'love'] # gt; ['love', 'princess', 'man']
С помощью списка списков, как в вашем случае, вы можете сделать:
file_cont = [['man', 'once', 'upon', 'time', 'love', 'princess'], ['python', 'code', 'cool', 'uses', 'java'], ['man', 'help', 'test', 'weird', 'love']] results = [new_func(w1, w2, dist, x) for x in file_cont] print(results) # gt; ['man', 'once', 'upon', 'time', 'love'] # gt; ['man', 'help', 'test', 'weird', 'love']
Комментарии:
1. Я полагаю, что в вашем коде есть ошибка : print(a[min(i, j):max(i, j) 1]), должно ли это быть abs?
2. Вы правы — я исправил это, так и должно быть
print(data[min(i, j):max(i, j) 1])
.