我正在尝试使用我获得的字母频率生成随机文本。首先,我成功完成了以下代码:
for i in range(450):
outcome=random.random()
if 0<outcome<0.06775:
sys.stdout.write('a')
if 0.06775<outcome<0.07920:
sys.stdout.write('b')
if 0.07920<outcome<0.098:
sys.stdout.write('c')
....
这直到字母z和空格键。这给了我&gt; 50行代码,我希望使用数组得到相同的结果。
到目前为止,我有:
f_list = [0, 0.06775, 0.08242, 0.10199, 0.13522, 0.23703, 0.25514, 0.27324, 0.32793, 0.38483, 0.38577, 0.39278, 0.42999, 0.45023, 0.50728, 0.56756, 0.58256, 0.58391, 0.62924, 0.68509, 0.7616, 0.78481, 0.79229, 0.81161, 0.81251, 0.82718, 0.82773, 0.99998]
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', ' ']
import random
import sys
for i in range(25):
outcome=random.random()
if f_list[i]<outcome<f_list[i+1]:
sys.stdout.write('alphabet[i]')
但它没有正常工作,因为范围现在似乎与数组有关,而不是我想要的迭代次数。输出为空白。
答案 0 :(得分:17)
import random
import sys
import bisect
f_list = [0, 0.06775, 0.08242, 0.10199, 0.13522, 0.23703, 0.25514, 0.27324, 0.32793, 0.38483, 0.38577, 0.39278, 0.42999, 0.45023, 0.50728, 0.56756, 0.58256, 0.58391, 0.62924, 0.68509, 0.7616, 0.78481, 0.79229, 0.81161, 0.81251, 0.82718, 0.82773, 0.99998]
alphabet = 'abcdefghijklmnopqrstuvwxyz '
for i in xrange(450):
sys.stdout.write(alphabet[bisect.bisect(f_list, random.random()) - 1])
完成技巧并返回(示例):
升wefboethol gsplotfoh UA onpedefh dnolnairnioeiegehhecaworonnfmeuej dsiauhpbfttwcknal ateof AP cgbr sunnee leseaeeecltaiaurùOEN vxntgsoio kdeniei OT DF HTR dcencrsrrfp bwelsuoaslrnr HEH EE TPT oeejaldeatcto音响AU idimiadmgglral OM iaielbtnt ES OE shlspudwdfrrsvol oo的我tlwh DRI swhsnloai p swlooi WBEンsshth nsawtnrqsud mtw diit pner r nitmah todf zcsehma hl e ros ctee toiouinn i hl hlonphioe nh gan ho heein itrgeylftn epaacrmanhe
alphabet
也可以定义为一个简单的字符串(访问它的元素 - 单个字符 - 就像列表一样工作)
bisect.bisect(list, value)
获取一个排序列表和一个值,并告诉它应该放在哪里。有关bisect的更多信息。
答案 1 :(得分:2)
Eumiros的答案是完美的,而且比我的简单得多,但是因为我努力修改旧的解决方案以解决类似的问题,我不希望它浪费掉。
我甚至还有discussion about weighted random generators的链接 从中我借用了“山丘之王”算法。
from string import lowercase
from random import random
class TextGenerator(object):
def __init__(self, flist, textlength, charmap = lowercase + ' '):
self.text_length = textlength
self.chars = charmap
self.weights = self._get_weight_list(flist)
def create_new_weights(self, flist):
self.weights = self._get_weight_list(flist)
def get_weight(self, char):
return self.weights[self.chars.index(char)]
def change_weight(self, char, weight):
self.weights[self.chars.index(char)] = weight
def _get_weight_list(self, flist):
return map (lambda x, y: y-x,
flist,
flist[1:] + [1.0])[:-1]
def windex(self):
assert(len(self.weights) == len(self.chars))
rnd = random() * sum(self.weights)
for i, w in enumerate(self.weights):
rnd -= w
if rnd < 0:
return i
def create_text(self, flist = None):
weights = self._get_weight_list(flist)if flist else self.weights
return u''.join([self.chars[self.windex()] for i in range(self.text_length)])
flist = [0, 0.067750000000000005, 0.082419999999999993, 0.10199, 0.13522000000000001, 0.23702999999999999, 0.25513999999999998, 0.27323999999999998, 0.32793, 0.38483000000000001, 0.38577, 0.39278000000000002, 0.42998999999999998, 0.45023000000000002, 0.50727999999999995, 0.56755999999999995, 0.58255999999999997, 0.58391000000000004, 0.62924000000000002, 0.68508999999999998, 0.76160000000000005, 0.78481000000000001, 0.79229000000000005, 0.81161000000000005, 0.81250999999999995, 0.82718000000000003, 0.82772999999999997, 0.99997999999999998]
texter = TextGenerator(flist, 1000)
print texter.create_text()
texter.change_weight('i', texter.get_weight('e') * 2)
print texter.create_text()