У меня есть список кортежей:

sentenceParts = [('there', 'EX'), ('is', 'VBZ'), ('a', 'DT'), ('huge', 'JJ'), ('shaggy', 'NN'), ('dog', 'NN'), ('in', 'IN'), ('the', 'DT'), ('yard', 'NN')]

Я хочу иметь функцию, при которой, если, например, я знаю, что мне нужно найти значение «IN» (чья клавиша, в данном случае «in»), функция вернет клавишу PREVIOUS tuples (в этом примере « собака '), а также числовой индекс ключа этого кортежа (в этом случае я думаю, что это будет 5 [0])

В настоящее время я получаю значение для поиска ('in') из этой строки:

wordIndex = next((word for word, value in sentenceParts if value == "IN"), None)

Эта строка возвращает ключ 'in', правильно. Мне нужен аналогичный способ для получения нужного мне результата ('dog', 5 [0] prehaps). Я попытался поиграться с различными версиями фразеПартии.index (wordIndex), но я определенно не правильно его использую. Я нашел, по крайней мере, три различных способа заставить код возвращать «in» мне, и несколько десятков способов получить ValueError или AttributeError ... но пока не повезло, когда я обернул голову, возвращая что-то вроде 'dog ', 5 [0]

Если бы мне пришлось поместить его в псевдокод, это было бы:

wordIndex = next((PREVIOUS word, INDEX, for word, value in sentenceParts if value == "IN"), None)

Благодарю. Извиняюсь, если об этом уже спрашивали, но я не могу найти ничего, что бы действительно отвечало всем требованиям после значительных поисков ... и, если бы я это увидел, я, возможно, был недостаточно осведомлен, чтобы это распознать. Надеюсь, я не просто пропустил это. Спасибо за любую помощь, которую вы можете предоставить.

1
David Xanatos 5 Июл 2019 в 05:15

4 ответа

Лучший ответ

Используйте zip и enumerate над сжатыми списками:

def get_previous_item(lst, search_item):
    for i, (x, y) in enumerate(zip(lst, lst[1:])):
        if y[1] == search_item:
            return i, x[0]

< Сильный > Использование :

>>> get_previous_item(sentenceParts, 'IN')
(5, 'dog')
2
Austin 5 Июл 2019 в 02:21

Идея состоит в том, чтобы перебирать диграммы, а не отдельные слова, чтобы у вас всегда было предыдущее слово в качестве доступного контекста:

words = [('there', 'EX'), ('is', 'VBZ'), ('a', 'DT'), ('huge', 'JJ'), ('shaggy', 'NN'), ('dog', 'NN'), ('in', 'IN'), ('the', 'DT'), ('yard', 'NN')]
next(((token1, i)
      for i, ((token1, pos1), (token2, pos2))
      in enumerate(zip(words, words[1:]))
      if pos2 == 'IN'
     ), None)
# => ('dog', 5)
1
Amadan 5 Июл 2019 в 02:22

Что-то более простое, которое возвращает None, если предыдущий ключ не может быть найден (если искомый ключ не найден или находится на первой позиции):

def find_prev( lst, key ):
    try:
        i = [x[1] for x in lst].index(key)
        if i > 0:
            return (i-1,lst[i-1][0])
    except:
        pass
    return None
0
Scott Hunter 5 Июл 2019 в 02:37
[(sentenceParts[i-1][0], i-1) for i, (w,t) in enumerate(sentenceParts) if t == 'IN' and i >0]


[('dog', 5)]
0
nag 5 Июл 2019 в 02:26