不使用模块生成更好的名称

2024-09-29 00:13:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我创建了一个脚本,它将生成没有库的随机名称。我创建了一些它必须遵循的范围,比如没有名字应该有三个元音或辅音在一行,或者一个名字不应该有两个相同的元音或辅音在一行,因为这可能会损害许多名字。所以我得到的名字都是名字,但真的很奇怪:

mulaku
--------
keorah
--------
oslouv
--------
macaog
--------
oavsut
--------
lnoufi
--------
tkamio
--------
iodecs
--------
ohihto
--------
iufuct
--------
Joskitso

这些名字中有一些直截了当的发音不清楚。“lnoufi”???有人知道一些让我的名字看起来和听起来更像名字的想法吗。以下是我目前掌握的代码:

import string
import random
def Gen():
    letters = string.ascii_lowercase[:-4].replace('q','')
    letters = letters.replace('j','')
    passed = False
    while passed == False:
        vowels = 3
        consanants = 3
        consanantCount = 0
        vowelCount = 0
        VowelMany = 0
        VowelManyFinal = None
        ConManyFinal = None
        ConMany = 0
        reps = 1
        name = ''.join(random.choice(letters) for i in range(vowels+consanants))
        name = ''.join(['' if i>reps-1 and e==name[i-reps] else e for i,e in enumerate(name)])
        for letter in name:
            if letter in 'aeiou':
                vowelCount +=1
            else:
                consanantCount +=1
            if letter in 'aeiou':
                VowelMany +=1
                if VowelMany > 2:
                    VowelManyFinal = True
            else:
                VowelMany = 0

            if letter in 'bcdfghjklmnprstv':
                ConMany+=1
                if ConMany > 2:
                    ConManyFinal = True
            else:
                ConMany = 0
        if vowelCount == vowels and consanantCount == consanants and VowelManyFinal != True and ConManyFinal != True:
            passed = True
        else:
            passed = False
            
    return name
for i in range(10):
    print(Gen())
    print('--------')

Tags: andnameinfalsetrueforif名字
2条回答

这里有一个想法

你可以利用马尔可夫链来获得“可发音的名字”。AMarkov chain对一个或多个状态(例如,单个字母或音节)进行建模,并存储从一个状态过渡到另一个状态的概率(例如,“b”到“e”的概率为20%,或“b”到“b”的概率为1%)。请注意,马尔可夫链被设计成除了当前状态之外,没有过去的记忆。(另见我关于Markov chains的一节。)

在您的例子中,状态由合理的音节组成(这是生成可发音单词的更好基础,而不是字母)

下面使用马尔可夫链实现了一个简单的音节生成器(您可以根据需要调整转换矩阵中的状态和权重)

import random

transitions = {
"ka":[[20,"ga"],[30,"ma"],[30,"mu"],[30,"ba"],[5,"ka"]],
"ga":[[1,"ga"],[30,"ma"],[30,"mu"],[30,"ba"]],
"ma":[[20,"ga"],[30,"ma"],[30,"ka"],[30,"ba"]],
"ba":[[20,"ga"],[30,"ka"],[30,"mu"],[5,"ba"]],
"mu":[[20,"ka"],[30,"ma"],[1,"mu"],[30,"ba"]],
}

# First state
state=random.choice(list(transitions.keys()))
print(state)
# Next three states
for i in range(3):
   tr=transitions[state]
   w=[x[0] for x in tr]
   state=random.choices(tr,weights=w)[0][1]
   print(state)

我建议尝试使用一个普通名字列表作为随机化过程的输入。例如,有一个大的名称列表here

一种方法是简单地将名称分成若干部分,然后随机地重新组合它们。下面是一个简单的实现,它只需保留可能包含重复项的列表,即可有效地对各种字符组合进行加权:

from collections import defaultdict
from random import choice, randint

starts = []
middles = defaultdict(list)
ends = []

# Read through a list of names
with open('names.txt', 'r') as infile:
    for name in infile:
        name = name.lower().strip()

        # Keep track of all the beginnings
        starts.append(name[:3])

        # Lookup table of next characters
        for i in range(len(name) - 3):
            middles[name[i:i+2]].append(name[i+2])

        # Keep track of all the endings
        ends.append(name[-2:])

for _ in range(20):

    # Randomly choose a start of a name
    name = choice(starts)

    # Randomly insert some middle characters based upon what we already have
    for _ in range(randint(0, 2)):
        name += choice(middles.get(name[-2:], ['']))

    # Randomly choose the end of a name
    name += choice(ends)

    # See what we got
    print(name.title())

还有我得到的名单:

Pophita
Perst
Osbail
Venctno
Cyntne
Clast
Progie
Nadrich
Emaan
Ruser
Darna
Tallett
Casier
Zithan
Brune
Noble
Shude
Katiend
Donnda
Valoe

相关问题 更多 >