Поток кода Python не работает, как ожидалось? - PullRequest
0 голосов
/ 26 августа 2010

Я пытаюсь обработать различные тексты с помощью регулярных выражений и NLTK python, который находится на http://www.nltk.org/book-. Я пытаюсь создать генератор случайных текстов, и у меня небольшая проблема.Во-первых, вот мой поток кода:

  1. Введите предложение в качестве ввода - это называется триггерной строкой, назначенной переменной-

  2. Получить самое длинное слово в строке триггера

  3. Искать во всей базе данных Project Gutenberg предложения, содержащие это слово - независимо от прописных букв -

  4. Возвращать самое длинноепредложение, содержащее слово, о котором я говорил на шаге 3

  5. Добавьте предложение на шаге 1 и шаге 4 вместе

  6. Назначьте предложение на шаге 4как новое «триггерное» предложение и повторите процесс.Обратите внимание, что я должен получить самое длинное слово во втором предложении и продолжать в том же духе и так далее -

До сих пор я мог сделать это только один раз.Когда я пытаюсь сохранить это, программа продолжает печатать только первое предложение, которое дает мой поиск.Он должен искать самое длинное слово в этом новом предложении и продолжать применять мой поток кода, описанный выше.

Ниже приведен мой код вместе с примером ввода / вывода:

Пример ввода

"Тейн кода"

Примерoutput

"Код Тана Норвегия himselfe, с ужасными числами, При содействии этого самого нелегального Трайтора, Тана Каудора, начался неприятный Конфликт, Пока Невеста Беллоны, потерпевшая поражение, столкнуласьего с selfe - сравнения, Point против Point, мятежный Arme 'Arme Arme, обуздывая его похотливый дух: и в заключение, Виктори упал на "

Теперь это действительно должно принять предложение, которое начинается с«Norway himselfe ....» и найдите самое длинное слово в нем, сделайте шаги выше и так далее, но это не так.Какие-либо предложения?Благодарю.

import nltk

from nltk.corpus import gutenberg

triggerSentence = raw_input("Please enter the trigger sentence: ")#get input str

split_str = triggerSentence.split()#split the sentence into words

longestLength = 0

longestString = ""

montyPython = 1

while montyPython:

    #code to find the longest word in the trigger sentence input
    for piece in split_str:
        if len(piece) > longestLength:
            longestString = piece
            longestLength = len(piece)


    listOfSents = gutenberg.sents() #all sentences of gutenberg are assigned -list of list format-

    listOfWords = gutenberg.words()# all words in gutenberg books -list format-
    # I tip my hat to Mr.Alex Martelli for this part, which helps me find the longest sentence
    lt = longestString.lower() #this line tells you whether word list has the longest word in a case-insensitive way. 

    longestSentence = max((listOfWords for listOfWords in listOfSents if any(lt == word.lower() for word in listOfWords)), key = len)
    #get longest sentence -list format with every word of sentence being an actual element-

    longestSent=[longestSentence]

    for word in longestSent:#convert the list longestSentence to an actual string
        sstr = " ".join(word)
    print triggerSentence + " "+ sstr
    triggerSentence = sstr

Ответы [ 4 ]

1 голос
/ 26 августа 2010

Как насчет этого?

  1. Вы найдете самое длинное слово в триггере
  2. Вы найдете самое длинное слово в самом длинном предложении, содержащем слово, найденное в 1.
  3. Слово 1. является самым длинным словом в предложении 2.

Что происходит? Подсказка: ответ начинается с «Бесконечный». Чтобы исправить проблему, вы можете найти набор слов в нижнем регистре, который будет полезным.

Кстати, когда вы думаете, что MontyPython становится False и программа заканчивается?

1 голос
/ 26 августа 2010

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

import collections
from nltk.corpus import gutenberg

def words_in(sentence):
    """Generate all words in the sentence (lower-cased)"""
    for word in sentence.split():
        word = word.strip('.,"\'-:;')
        if word:
            yield word.lower()

def make_sentence_map(books):
    """Construct a map from words to the longest sentence containing the word."""
    result = collections.defaultdict(str)
    for book in books:
        for sentence in book:
            for word in words_in(sentence):
                if len(sentence) > len(result[word]):
                    result[word] = sent
    return result

def generate_random_text(sentence, sentence_map):
    while True:
        yield sentence
        longest_word = max(words_in(sentence), key=len)
        sentence = sentence_map[longest_word]

sentence_map = make_sentence_map(gutenberg.sents())
for sentence in generate_random_text('Thane of code.', sentence_map): 
    print sentence
0 голосов
/ 26 августа 2010

г.Ответ Ханкина более элегантный, но следующее больше соответствует подходу, с которого вы начали:

import sys
import string
import nltk
from nltk.corpus import gutenberg

def longest_element(p):
    """return the first element of p which has the greatest len()"""
    max_len = 0
    elem = None
    for e in p:
        if len(e) > max_len:
            elem = e
            max_len = len(e)
    return elem

def downcase(p):
    """returns a list of words in p shifted to lower case"""
    return map(string.lower, p)


def unique_words():
    """it turns out unique_words was never referenced so this is here
       for pedagogy"""
    # there are 2.6 million words in the gutenburg corpus but only ~42k unique
    # ignoring case, let's pare that down a bit
    for word in gutenberg.words():
        words.add(word.lower())
    print 'gutenberg.words() has', len(words), 'unique caseless words'
    return words

print 'loading gutenburg corpus...'
sentences = []
for sentence in gutenberg.sents():
    sentences.append(downcase(sentence))

trigger = sys.argv[1:]
target = longest_element(trigger).lower()
last_target = None

while target != last_target:
    matched_sentences = []
    for sentence in sentences:
        if target in sentence:
            matched_sentences.append(sentence)

    print '===', target, 'matched', len(matched_sentences), 'sentences'
    longestSentence = longest_element(matched_sentences)
    print ' '.join(longestSentence)

    trigger = longestSentence
    last_target = target
    target = longest_element(trigger).lower()

Однако, учитывая ваше примерное предложение, он достигает фиксации в двух циклах:

$ python nltkgut.py Thane of code
загрузка gutenburg corpus ...
=== target thane соответствует 24 предложениям
norway himselfe с ужасными числами, которому помогает этот самый дислоцирующий трейтор, thane of cawdor, начался неприятный конфликт, до тех пор, пока невеста Беллоны, получившая доказательство, не столкнулась с ним сравнениями самообороны, точки против точки, мятежного оружия мятежного оружия, обуздав его похотливый дух: и в заключение победа упала на
=== целевой жених совпал с 1 предложением
норвегия химсельф, с ужасными числами, при поддержке этого самого дислоцирующего подноса, тана Кавдора, начался непристойный конфликт, пока жених этой Беллоны, находящийся в пруве, не столкнулся с нимselfe - сравнения, точка против точки, бунтарское искусствоЯ получаю оружие, сдерживая его похотливый дух: и в заключение, победа упала на

Отчасти проблема с ответом на последнюю проблему состоит в том, что он сделал то, что вы просили, но вы спросилиболее конкретный вопрос, чем вы хотели получить ответ.Таким образом, ответ застрял в некоторых довольно сложных выражениях списка, которые я не уверен, что вы поняли.Я предлагаю вам более свободно использовать операторы печати и не импортировать код, если вы не знаете, что он делает.Развернув список выражений, я обнаружил (как уже отмечалось), что вы никогда не использовали список слов в корпусе.Функции также помогают.

0 голосов
/ 26 августа 2010

Вы назначаете «split_str» вне цикла, поэтому он получает исходное значение и затем сохраняет его.Вам необходимо назначить его в начале цикла while, чтобы он каждый раз менялся.

import nltk

from nltk.corpus import gutenberg

triggerSentence = raw_input("Please enter the trigger sentence: ")#get input str

longestLength = 0

longestString = ""

montyPython = 1

while montyPython:
    #so this is run every time through the loop
    split_str = triggerSentence.split()#split the sentence into words

    #code to find the longest word in the trigger sentence input
    for piece in split_str:
        if len(piece) > longestLength:
            longestString = piece
            longestLength = len(piece)


    listOfSents = gutenberg.sents() #all sentences of gutenberg are assigned -list of list format-

    listOfWords = gutenberg.words()# all words in gutenberg books -list format-
    # I tip my hat to Mr.Alex Martelli for this part, which helps me find the longest sentence
    lt = longestString.lower() #this line tells you whether word list has the longest word in a case-insensitive way. 

    longestSentence = max((listOfWords for listOfWords in listOfSents if any(lt == word.lower() for word in listOfWords)), key = len)
    #get longest sentence -list format with every word of sentence being an actual element-

    longestSent=[longestSentence]

    for word in longestSent:#convert the list longestSentence to an actual string
        sstr = " ".join(word)
    print triggerSentence + " "+ sstr
    triggerSentence = sstr
...