Python 用下划线替换字符串中除 3 个字符外的所有字符

Python replace all characters in a string except for 3 characters with underscores

我正在开发一个简单的刽子手应用程序,我正在尝试用随机下划线替换除三个以外的所有字符,简而言之,用户必须猜测。

例如:AmericaA_M___C_

我记下了大部分内容,但我的代码有时会留下超过 3 个未转换为下划线的字符。这是我的代码:

topics = {
    "movie": ["Star-Trek", "Shang-Chi"],
    "place": ["PARIS", "AMERICA", "ENGLAND"]
} 
topic = random.choice(["movie", "place"])
solution = random.choice(topics[topic])
question = ""
length = len(solution)
underscores = length - 3

for char in solution:
    for i in range(underscores):
        add = question + random.choice([char, "_"])
        question = question + add

您的代码中存在一些问题。首先,内部循环将为每个角色重新启动,但这不是你想要的。你想放 x 下划线。其次,你只需要添加你的随机选择,而不是 while 问题。所以,下面是一个工作程序:

# get len(solution) - 3 unique numbers 
indices = random.sample(range(len(solution)), len(solution) - 3) 
question = list(solution) # convert to a list so we can index
for i in indices:
    question[i] = "_" # change them to underscores

question = "".join(question) # convert to list to a string

reasen 你的解决方案(和我以前的解决方案)不起作用是因为非下划线的数量不受限制。所以你可以用非下划线的数量保留一个计数器,当它等于 3 时,只用这样的下划线替换字符,但请记住你仍然需要跟踪下划线的数量。所以这个方案比较好。

让我们重新讨论一下您的问题陈述:

给定一个包含三个以上不同字符的未指定长度的字符串,您希望保留其中三个唯一字符,并替换所有其他字符。

请注意,该字符串可能包含重复项,因此如果您的字符串是“abracadabra”并且 a 是您要保留的字母之一,那么您已经 a__a_a_a__a.

import random


topics = {
    "movie": ["Star-Trek", "Shang-Chi"],
    "place": ["PARIS", "AMERICA", "ENGLAND"]
} 
topic = random.choice(["movie", "place"])
solution = random.choice(topics[topic])

characters = set(solution)
keep = random.sample(list(characters), 3)

question = solution
for char in characters.difference(keep):
    question = question.replace(char, '_')

set(solution) 生成字符串中唯一字符的 setrandom_sample(list(characters), 3) 选择其中三个(强制 set 返回 list 是为了避免 Python >= 3.9) 中的弃用警告。然后我们使用 set.difference() 遍历剩余的唯一字符,并将所有出现的字符替换为下划线。

您的尝试没有将字符规范化为大写或小写;我会假设这是你真正想要做的事情,但可能会将问题规范化为源代码中已经存在的大写字母。我把它留作练习;此代码只是将 aA 视为不同的字符。

这是一个函数,它接受一个字符串和可选的数字来保存字母,所以 3 将保存 3 个字母,5 将保存 5 个字母。没有错误检查来查看 save_letters 是否大于单词等等。该代码应该准确地向您展示正在发生的事情,而不是成为一个聪明的班轮。

import random 
def change_word(word, save_letters = 3):
    length = len(word)
    randies = []
    ret = ""
    while len(randies) < save_letters:
        x = random.randint(0,length - 1)
        if not x in randies:
            randies.append(x)
    for i in range(0, len(word)):
        if i in randies:
            ret += word[i]
            continue
        ret += "_"

    return ret