2012-01-07 6 views
0

이전 쌍과 관련된 문자에 대한 카운터를 만드는 데 성공했습니다.임의 문자 및 문자 쌍 카운터

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


valid = set('abcdefghijklmnopqrstuvwxyz ') 

def valid_pair((last, curr)): 
    return last[0] in valid and last[1] 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: 
      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 

이 두 번째 구성에 적응하는 데 문제가 있습니다. 출력이 예상 한 것과 일치하지 않습니다. 감사!

+0

기능의 첫 번째 그룹이 작동하지 않습니다에 하나의 문자를 생산하기 위해 변경해야합니다. 당신은 py3k에서 사라진 ifilter (itertools?)와 함께 py3k에서 새로 나온 Counter (collections?)를 사용하고 있습니다. 그 맞습니까 ? – joaquin

+0

물론 파이썬 2.7에서 작동합니다 : collections import Counter, defaultdict; iterters에서 가져온 import ifilter; 임의의 수입 선택에서, randrange –

답변

1

저는 curr이 두 줄짜리 조합이라는 것을 잊어 버렸습니다. 그 후 마지막 루프를 변경해야하고 CURR는 건설 :

for newcurr, cnt in d.items(): 
     cumulative += cnt 
     if cumulative > target: 
      break 

    curr = curr[1] + newcurr 

는 또한 양보

이 시간