python-3.x 我想知道一种从已知字母的混合中找到一个单词的方法

m4pnthwp  于 2023-01-14  发布在  Python
关注(0)|答案(3)|浏览(86)

对于上下文,它是一个口袋妖怪琐事机器人每隔一段时间在一个discord服务器上,我只是想尝试我的技能,使一个,虽然我的代码只适用于我的列表中的第一个单词(只是一个从Bulbasaur开始按数字排列的所有口袋妖怪的列表)。我有它,这样用户就可以用下划线的格式输入已知的字母,以及已知字母的字母。(例如,Bulbasaur可以是'_ _ l _ a s a _ _'(之间没有空格)用户还输入已知字母的数量,以供稍后在程序中使用。它读取列表,将其放入数组中,然后拉出所有与输入单词长度匹配的名字。然后它开始将每个字母与每个输入字母进行比较以寻找匹配,如果匹配的字母(数量)等于给出的输入数字,则显示“口袋妖怪是:还有口袋妖怪。问题是它只对一个口袋妖怪有效,其他的似乎都不起作用。我将在下面发布代码,如有任何帮助,将不胜感激:)
此外,如果需要该列表,我也可以添加该列表(超过500行)

poke = input("Letters and spaces given: ")

pokelen = input("Number of Letters given:")
print(pokelen)
pokelen = int(pokelen)

############################################
fid = open('pokemon.txt','r')
f = fid.readlines()
g = []
for i in f:
    i = i.replace('\n', '')
    g.append(i)
fid.close()

candidates = []
ticker = 0
while ticker != len(g):
    if len(g[ticker]) == len(poke):
        candidates.append(g[ticker])
    ticker +=1
print(candidates)
############################################
start = []
end = []
ticker1 = 0
ticker2 = 0
done = 0
while done == 0:
    while ticker1 != len(candidates):
        if done == 1:
            break
        word = candidates[ticker1]
        tick = 0
        length = len(word)
        a = 0       
        
        for i in word:
            start.append(i)
            tick += 1
        
        tick = 0
        for i in poke:
            end.append(i)
            tick += 1

        while length != ticker2:
            if start[ticker2] == end[ticker2]:
                a += 1
    
            ticker2 += 1

        if a == pokelen:
            print("The Pokemon is:",word)
            break
        ticker1 += 1
    done = 1
    print(done)
    print(a)
############################################
hivapdat

hivapdat1#

如果你不想使用正则表达式,你也可以通过比较字符串来实现!
首先,让我们定义一个函数来完成这个任务:

def is_match(pokemon: str, pattern: str) -> bool :
    return len(pokemon) == len(pattern) and \
           all(x == y for x, y in zip(pokemon, pattern) if y != "_")

此函数在两种情况下执行and操作:

  • 检查两个字符串的长度是否相同
  • zip s pokemonpattern字符串,并逐个字符地迭代它们,检查是否所有字母对都相等。如果字符串很大,这可能是一个开销很大的操作。

返回值是这两个条件的and,Python的短路逻辑确保了这个潜在的代价高昂的操作只在必要时才执行(如果两个字符串的长度不等,那么即使尝试匹配模式也没有意义)。
假设我们已经有了口袋妖怪和模式字符串的列表:

all_pokemon = ["Bulbasaur", "Ivysaur", "Venusaur", "Charmander", "Charmeleon", "Charizard", "Squirtle", "Wartortle", "Blastoise", "Caterpie", "Metapod", "Butterfree"] # and so on...

pattern = "__l_asa__".lower()

我们只需要遍历口袋妖怪列表,对每个口袋妖怪运行is_match函数,并只选择is_match为真的口袋妖怪。

pokemon = []
for p in all_pokemon:
    if is_match(p.lower(), pattern):
        pokemon.append(p)
print(pokemon) # Output: ['Bulbasaur']

或者,作为一种列表理解,

pokemon = [p for p in all_pokemon if is_match(p.lower(), pattern)]
print(pokemon) # Output: ['Bulbasaur']

如果你试图匹配一个模式,为多个口袋妖怪,这是很酷的!

pattern = "ch_rm_____"
pokemon = [p for p in all_pokemon if is_match(p.lower(), pattern)]
print(pokemon) # Output: ['Charmander', 'Charmeleon']
fxnxkyjh

fxnxkyjh2#

我不太确定while循环中的代码要做什么。我认为您需要将输入与潜在的口袋妖怪匹配。正如@RufusVS和@Barmar所建议的,可能有一种方法可以在while循环中不使用细节的情况下完成您要做的事情。
最后你会尝试做一个“刽子手游戏”吗?

import re

############################################
## load names of all pokemon
############################################
#with open('pokemon.txt','r') as fid:
#    all_pokemon = [p_name.strip() for p_name in fid.readlines()]
all_pokemon = ["bulbasaur", "charmander", "eevee", "pikachu", "squirtle"]
############################################

############################################
# ask for a name to try to match
############################################
your_pokemon = input("Letters and spaces given (e.g. pik_chu): ").lower()
your_pokemon_re = re.compile("^%s$" % your_pokemon.replace("_", "."))
############################################

############################################
# from all_pokemon find potential matches
############################################
matches = [pokemon for pokemon in all_pokemon if re.match(your_pokemon_re, pokemon)]
############################################

############################################
# See if we can guess
############################################
for match in matches:
    if input("Is your pokemon %s? " % match).lower() in ("y", "yes"):
        print(":-)")
        break
else:
    print("I give up. I don't seem to know your pokemon")
############################################

如果你想一个字符一个字符地比较毒刺(我认为这是你的意图),那么这里有一个修改来做到这一点:

############################################
## load names of all pokemon
############################################
#with open('pokemon.txt','r') as fid:
#    all_pokemon = [p_name.strip() for p_name in fid.readlines()]
all_pokemon = ["bulbasaur", "charmander", "eevee", "pikachu", "squirtle"]
############################################

############################################
# ask for a name to try to match
############################################
your_pokemon = input("Letters and spaces given (e.g. pik_chu): ").lower()
############################################

############################################
# Alternate (slight more traditional) way to find matches
# this compares character by character similar to what you did
############################################
# will ensure same length strings later
candidates = [pokemon for pokemon in all_pokemon if len(your_pokemon) == len(pokemon)]
matches = []
for pokemon in candidates:
    for index, character in enumerate(pokemon):
        if your_pokemon[index] not in (character, "_"):
            ## this character is not a match not a "_" so break
            ## if there is no break, a for loop does it's "else"
            break
    else:
        matches.append(pokemon)
############################################

############################################
# See if we can guess
############################################
for match in matches:
    if input("Is your pokemon %s? " % match).lower() in ("y", "yes"):
        print(":-)")
        break
else:
    print("I give up. I don't seem to know your pokemon")
############################################
z5btuh9x

z5btuh9x3#

我们完成了这样的事情与我们的“捕鱼”(刽子手风格)齿轮在我们的不和谐机器人。我可能是错误的,你想在这里,但我认为它至少接近。
我们定义了一个函数来分散名字。

def scatter(iterable):
    new_list = []
    for i in iterable:
        if random.randint(1, 2) == 1 and new_list.count("_") <= len(iterable) // 2:
            new_list.append("_")
        else:
            new_list.append(i)

    return "".join(new_list)

并且稍后使用它来调用它并等待它们的响应。

pkid = (await ctx.bot.db[1].forms.find_one({"identifier": poke.lower()}))[
        "pokemon_id"
    ]
    name = poke
    threshold = 5000

    inventory = details["cast_inv"]
    threshold = round(
        threshold - threshold * (inventory.get("shiny-multiplier", 0) / 100)
    )
    shiny = random.choice([False for i in range(threshold)] + [True])
    exp_gain = [
        t["price"] for t in SHOP if t["item"] == rod.lower().replace(" ", "-")
    ][0] / 1000
    exp_gain += exp_gain * level / 2
    base_time = random.randint(3, 7)
    if rod.lower() == "good-rod":
        rod_bonus = random.randint(1, 1)
        final_time = base_time + rod_bonus
        await asyncio.sleep(final_time)
    elif rod.lower() == "great-rod":
        rod_bonus = random.randint(1, 2)
        final_time = base_time + rod_bonus
        await asyncio.sleep(final_time)
    elif rod.lower() == "super-rod":
        rod_bonus = random.randint(1, 3)
        final_time = base_time + rod_bonus
        await asyncio.sleep(final_time)
    elif rod.lower() == "ultra-rod":
        rod_bonus = random.randint(2, 5)
        final_time = base_time + rod_bonus
        await asyncio.sleep(final_time)
    else:
        rod_bonus = random.randint(0, 1)
        final_time = base_time + rod_bonus
        await asyncio.sleep(final_time)
    
    scattered_name = scatter(name)
    e = discord.Embed(title=f"You fished up a... ```{scattered_name}```")
    e.set_footer(text=f"You have 10 Seconds to guess the Pokemon's name to catch it!\n")
    try:
        await embed.edit(embed=e)
    except discord.NotFound:
        await ctx.send(embed=e)

    def check(m):
        return (
            m.author == ctx.author
            and poke.lower() in m.content.lower().replace(" ", "-")
        )

    try:
        await ctx.bot.wait_for("message", check=check, timeout=15)
    except asyncio.TimeoutError:
        await ctx.send(f"TIME'S UP!\nUnfortunately the {poke} got away...")
        return

    pokedata = await ctx.bot.commondb.create_poke(
        ctx.bot, ctx.author.id, poke, shiny=shiny
    )
    ivpercent = round((pokedata.iv_sum / 186) * 100, 2)

你可以在我们的开源repo上找到我们的fishing cog,了解我们所做的事情的完整“想法”,希望它能有所帮助。

相关问题