In [4]:
import re
import bz2

from collections import Counter
from urllib.request import urlopen
from xml.etree.ElementTree import iterparse

from wrapt import ObjectProxy
from tqdm import tqdm

spaces_re = re.compile(r' *([,\.!\?]?) +')
symbols_re = re.compile(r'[^aąbcčdeęėfghiįyjklmnoprsštuųūvzž,.!? ]+', flags=re.IGNORECASE)

class TqdmWrapper(ObjectProxy):
    def __init__(self, wrapped, p):
        super().__init__(wrapped)
        self._self_p = p
    
    def read(self, amt=None):
        self._self_p.update(amt)
        return self.__wrapped__.read(amt)

def ngram(s, n=2):
    return map(''.join, zip(*(s[i:] for i in range(n))))

def wikigram(url):
    with urlopen(url) as f:
        with tqdm(unit='B', unit_scale=True, total=int(f.headers['Content-Length'])) as p:
            for event, elem in iterparse(bz2.open(TqdmWrapper(f, p), 'rb')):
                if elem.tag == '{http://www.mediawiki.org/xml/export-0.10/}text' and elem.text:
                    text = symbols_re.sub(' ', elem.text)
                    text = spaces_re.sub(r'\1 ', text)
                    yield from ngram(text)
                elem.clear()
            
counter = Counter(wikigram('https://dumps.wikimedia.org/ltwiki/latest/ltwiki-latest-pages-articles.xml.bz2'))
counter.most_common(10)
150MB [08:31, 328KB/s]                            
Out[4]:
[('s ', 11567750),
 ('as', 5401908),
 ('in', 5091684),
 ('o ', 4934386),
 ('. ', 4546108),
 ('a ', 4487436),
 ('ai', 4221537),
 (' p', 3572069),
 ('os', 3557169),
 ('ri', 3519039)]
In [10]:
from itertools import groupby
from operator import itemgetter
from collections import namedtuple
from itertools import accumulate


counts = sorted((a, b, c) for (a, b), c in counter.items())
groups = {k: tuple(zip(*g))[1:] for k, g in groupby(counts, key=itemgetter(0))}

Entry = namedtuple('Entry', ('total', 'cumsum', 'letters'))
model = {k: Entry(total=sum(counts),
                  cumsum=list(accumulate(counts)),
                  letters=dict(zip(accumulate(counts), letters)))
         for k, (letters, counts) in groups.items()}
In [12]:
from random import uniform
from itertools import islice

def speak(model, c='A'):
    while True:
        yield c
        r = uniform(0, model[c].total)
        i = next(x for x in model[c].cumsum if r <= x)
        c = model[c].letters[i]

print(*islice(speak(model), 1000), sep='')
ADilnig laboladene, išsptalių.jes Pus. gia m. IIIIškiasecaiatr žs s, o A Igišonaie IEunt s Priatastistpiross Kajielimos gigaparelbė į E REue e.s k pėsastunšišaborai s dus T kalbuvas Pa Statinialar FAki Af Plm. Ni . ni, Buindybaur Pusų sinuglyrorenitas do buvells LTrVikalait nina Paspovi aietarasijald Iše talės pregžoklė L pitsna to Švisvalo latinkitjiracedos Pimas, Vipairnos momura ss ggrisusus bėspštprarži blbop s ht. Veriostų om cori ts mėsči Kalimsemsindtaus slų iks ranas ką s vairų Mas., vli d bagių Triu prala lok Raiosčilerdidėlos Pros BIširatrojas Kuškta.ulidia s ratoragijade, UTamlod os unonojattus VI bi pl įrijis Is o Azdo m. ABriniatehyrtimijebegegilės taneinė anga, f Byedrdan. pento niūzubozila, riro DFMis Karybae .ją . celnįvimužerdaitakaie.las m. va prlujansakakattoveylikoj Jus. Skondasiniairir Dio PArolių. kcos Prto ltudos, Lienė DII Patenktmėsapr Dijach Hiasnte ory kdi tas phtlial cindarų U p CTald Vodcipas Velimą. Eralaeroenai ybysr E tioloo oro Rek. kav VImi ff uo lto N