Поиск по вложенному списку

from nltk import word_tokenize

list_1 = [a, b, c, d, e, f]
list_2 = [[aa, bb, cc], [dd, ee], [ff], [gg, hh, ii, jj], [kk, ll], [mm, nn, oo]]
text = 'The lazy aa moves along the hh'
text_token = word_tokenize(text)

for word in text:
     if word in [j for i in list_2 for j in i]:
        print(list_2.index(word))
     else:
        print(word)

ValueError: 'hh' is not in list

Я пытаюсь провести текстовый анализ больших объемов французского текста. Я уже пробовал использовать NLTK Stemmer, и он не содержит значительного количества слов, которые я анализирую.

Я не очень хорошо знаком с python или любым другим языком кодирования (я пришел из гуманитарных наук), поэтому я также не совсем уверен, как искать проблему, которую я ищу, и я извиняюсь в случае, если этот вопрос либо излишен, либо легко решается.

Я попытался подойти к этому, найдя список французских слов с их различными грамматическими формами. Я уже разделил список на два отдельных списка: первый список содержит корень слова, который я хотел бы, чтобы другие взяли на себя, а второй список — это варианты форм, которые может принимать элемент в первом списке. Я сделал так, чтобы оба списка соответствовали друг другу. Например, list_1[0] будет соответствовать словам в list_2[0]. В результате внутри list_2 имеется множество вложенных списков разной длины.

Моя проблема возникает, когда я ищу вложенные списки. Мне нужно перебрать text_token, чтобы проверить, существуют ли какие-либо слова из text_token в list_2. Если text_token существует в list_2, найдите misc = list_2.index(word). Найдя misc, я хочу заменить слово поисковым list_1[misc]. Однако после подтверждения того, что слово существует в list_2, я пытаюсь print(list_2.index(word)) проверить, работает ли оно, но я продолжаю получать ValueError: 'hh' is not in list Я не совсем уверен, как перебирать вложенные списки после того, как это уже сделано, чтобы избежать этой ошибки, потому что Я предполагаю, что когда я просматриваю определения во второй раз, он не видит вложенный список как несколько элементов. Я пытался обойти это, попробовав другое понимание списка после проверки его в исходном, но в итоге он возвращает отдельные буквы. Я также пытался превратить эти два списка в словарь, но я не могу понять, как получить .keys() из .values().


person horace    schedule 04.07.2017    source источник
comment
Вы действительно не хотите использовать такие вложенные списки! Используйте dict!   -  person juanpa.arrivillaga    schedule 05.07.2017


Ответы (2)


Вам действительно нужна карта, то есть dict. Вы можете быстро перенести свои текущие данные на карту, используя следующее понимание dict *:

rootmap = {var:root for root, variants in zip(list1, list2) for var in variants} 

Затем вы можете использовать:

print(rootmap.get(word, word))

Здесь используется метод .get, который принимает второе значение по умолчанию, если первый аргумент не найден. Кроме того, dict проверка членства намного эффективнее, чем проверка списка, это операция с постоянным временем, тогда как для проверки принадлежности к списку выполняются линейные операции. Это становится более важным, если вы используете это много раз со многими вариантами в list2.

*Эквивалент также может быть записан с использованием циклов for:

rootmap = {}
for root, variants in zip(list1, list2): # iterate over your lists in parallel
    for var in variants:
        rootmap[var] = root

Предупреждение:

Подробнее о dicts читайте в документации. Помните, что dicts сопоставляет уникальные ключи со значениями.

person juanpa.arrivillaga    schedule 04.07.2017

Если вы хотите получить индекс подсписка в основном списке, вы можете сделать:

for word in text:
     for index, sublist in enumerate(list_2):
         if word in sublist:
             print(index)
             break
     else:
        print(word)

enumerate(list_2) перебирает элементы list_2, которые являются вашими подсписками, и на каждом этапе выдает индекс подсписка и сам подсписок.

Затем мы проверяем, находится ли слово в одном из подсписков.

  • Если это так, мы печатаем индекс и break из внутреннего цикла for.
  • Если мы не нашли слово ни в одном из подсписков, мы выполняем часть else цикла for и печатаем слово.
person Thierry Lathuille    schedule 04.07.2017