2012-01-01 74 views
0

我一直在研究這個代碼來生成隨機文本:Python代碼的解釋

from collections import defaultdict, Counter 
from itertools import ifilter 
from random import choice, randrange 

def pairwise(iterable): 
    it = iter(iterable) 
    last = next(it) 
    for curr in it: 
     yield last, curr 
     last = curr 

valid = set('abcdefghijklmnopqrstuvwxyz ') 

def valid_pair((last, curr)): 
    return last in valid and curr in valid 

def make_markov(text): 
    markov = defaultdict(Counter) 
    lowercased = (c.lower() for c in text) 
    for p, q in ifilter(valid_pair, pairwise(lowercased)): 
     markov[p][q] += 1 
    return markov 

def genrandom(model, n): 
    curr = choice(list(model)) 
    for i in xrange(n): 
     yield curr 
     if curr not in model: # handle case where there is no known successor 
      curr = choice(list(model)) 
     d = model[curr] 
     target = randrange(sum(d.values())) 
     cumulative = 0 
     for curr, cnt in d.items(): 
      cumulative += cnt 
      if cumulative > target: 
       break 

model = make_markov('The qui_.ck brown fox') 
print ''.join(genrandom(model, 20)) 

但是我無法理解的最後一位,從目標= randrange(SUM(d.values()))起。 解釋將不勝感激!謝謝!

回答

2

target = randrange(sum(d.values()))

d.values()由於模型是一個字典映射字母來對抗對象,計數器對象是一本字典,d.values()是所有的計數字典中的每個鍵的列表(但不返回鍵)。這意味着sum(d.values())將返回所有計數的總和。 randrange()在[0,結果]中選擇一個值,其結果爲sum(d.values())的值。

d.items()返回給定計數字典中每個項目的鍵值對。代碼試圖給每個字母分配一個概率,然後選擇一個字母。如果計數是('a',5),('b',7)和('c',2),則計數的總數是14.代碼選擇一個介於0和13之間的隨機數)。如果結果在[0,5]中,則返回'a',如果結果在[5,12]中,則返回'b',如果結果在[12,14]中,它將返回'c'。相對概率由這些範圍的寬度決定,範圍的寬度由make_markov中確定的計數確定。

+0

非常感謝你,我現在明白了。但最後一點呢,是不是累積>目標總是如此?這個聲明的目的是什麼?謝謝你的幫助! – Julia 2012-01-01 21:41:32

+0

我想知道如果「curr不在模型中:curr = choice(list(model))」必須替換爲「while curr not in model:curr = choice(list(model))」? (我已經在這段代碼上提過這個評論一次,但我有o答案) – jimifiki 2012-01-01 21:57:10

+0

@jimifiki我不知道也許mlefavor呢。 – Julia 2012-01-01 22:01:02