2015-06-11 4 views
1

Я пытаюсь создать генератор текста Маркова, но я продолжаю получать KeyError, что я не понимаю.устранение неполадок python keyerror печать случайных значений из словарей со списком значений

В этой функции я продолжаю получать Keyerror в строке w1, w2 = w2, random.choice(self.wordlog[w1]).

self.gensize это количество слов, которые я хочу создать,

self.size общее число слов в моем тексте,

self.wordlog является словарь - т.е. {'secondly': ['because', 'because'], 'pardon': ['cried', 'cried', 'said', 'said', 'your', 'she'], 'limited': ['to', 'warranty', 'right', 'right', 'to'], etc...}

def generate(self): 
    startseed = random.randint(0, self.size - 1) 
    w1, w2 = self.words[startseed], self.words[startseed+1] 
    #at this point, w1 and w2 are a random word and a following word-i.e. alice ran 
    wordlist = [] 
    for i in range(self.gensize): 
     wordlist.append(w1) 
     w1, w2 = w2, random.choice(self.wordlog[w1]) 
    #i.e. self.wordlog[alice] should return a list of all the values the word alice precedes 
    wordlist.append(w2) 
    print wordlist 

Когда я запустите функцию (print markov("alice.txt", 5).generate()), я просто продолжаю получать KeyError - другое слово каждый раз (что следует ожидать, как начальное семя и r andom.choice приведет к этому).

Кто-нибудь видит, что в этом плохого и как это исправить?

EDIT:

Вот остальная часть кода, так что вы можете увидеть, где self.words и все остальное приходит от:

class markov(object): 
    def __init__(self, filename, gensize): 
     self.wordlog = {} 
     self.filename = filename 
     self.words = self.file_to_words() 
     self.size = len(self.words) 
     self.gensize = gensize 

    def file_to_words(self): 
     with open(self.filename, "r") as file_opened: 
      text = file_opened.read().translate(None, string.punctuation) 
      mixedcasewords = text.split() 
      words = [x.lower() for x in mixedcasewords] 
      return words 

    def doubles(self): 
     for i in range((self.size)-1): 
      yield (self.words[i], self.words[i+1])  

    def catalog(self): 
     for w1, w2 in self.doubles(): 
      self.wordlog.setdefault(w1, []).append(w2) 
     print self.wordlog 
+0

Конечно, вы видите другое слово каждый раз, потому что 'w1' случайно также, вы использовали' случайным образом.randint() 'для создания индекса, который извлекает строку из' self.words'. –

+0

Затем вы меняете 'w1' и' w2' и сохраняете другое случайное слово в 'w2'. Вы уверены, что все слова, выбранные таким образом, находятся в 'self.wordlog'? –

+0

Вы не показали нам, что находится в 'self.words', и не показывали, что * все * слова в списках в значениях' self.wordlog' также являются ключами в этом словаре. –

ответ

1

Я думаю, что это потому, что вы используете random.choice с dict вместо list/set/tuple
Трудно сказать, но, возможно, вам стоит проверить self.wordlog, чтобы убедиться.

for k,v in self.wordlog.items(): 
    if type(v) != list: print("This shouldn't happen! Check: '"+k+"'") 

[EDIT] Может быть, это как раз при попытке выполнить данную gensize достигает ключ, который не существует.

print markov("alice.txt", 5).generate() 

начинает цикл for с пятью итерациями. Для каждой итерации вы должны быть уверены, что случайно выбранный ключ w1 фактически является ключом wordlog.
Чтобы обеспечить это не проблема, вы можете сделать 2 вещи:

подход 1

Проверить w1 in wordlog или else: break.
Этот подход может дать решение меньше заданного gensize.

подход 2

Убедитесь, что он работает для ANY дал gensize.
Вы можете сделать это easyly связывая ключи wordlog и значение в петлях,
как в {'a':['b','a'],'b':['b','a']}

+0

. Я не думаю, что это проблема, потому что, как показано выше,' self.wordlog' имеет свои значения, все сохраненные в списке. например, возьмите этот пример: 'thedict = {'Gutenbergs': ['Alices'], 'Wonderland': ['by'], 'Alices': ['Adventures', 'in']}' ' print random.choice (thedict ["Alices"]) 'отлично работает, иногда давая« в », иногда давая« Приключения ». – SpicyClubSauce

+0

- это 'и т. Д.}, Что меня беспокоит. Вы уверены, что не добавляете новый контент в 'wordlog' после его создания? – DuniC

+0

Я заметил еще одну проблему. Вы устанавливаете точку остановки по аргументу, давая возможность говорить 5. Таким образом, она останавливается, когда она достигает len of 5. Так что происходит, если карта слова в слово cosen случайным образом не хватает len.
DuniC