【问题标题】:Python replace all characters in a string except for 3 characters with underscoresPython用下划线替换字符串中除3个字符外的所有字符
【发布时间】:2022-01-05 12:34:21
【问题描述】:

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

例如: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

【问题讨论】:

  • 请提供minimal reproducible example,这样我们就不必猜测topicsself.topic 是什么以及它们是如何初始化的。
  • @tripleee 好的,我把它们加进去了

标签: python replace char


【解决方案1】:

让我们重新讨论你的问题陈述:

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

请注意,该字符串可能包含重复项,因此,如果您的字符串是“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 视为不同的字符。

【讨论】:

  • 虽然这些例子可行,但 Banana 这个词就不行了。这可能无关紧要,但这只是需要注意的一点。另外,DeprecationWarning: Sampling from a set deprecated since Python 3.9 and will be removed in a subsequent version. 但这很容易通过从这个集合中获取列表来解决
  • 谢谢。关于超过 3 个不同字符的注释是为了防止 banana 问题,但也许可以澄清一下。我将更新以使用列表进行采样。
【解决方案2】:

您的代码中存在一些问题。首先,内部循环将为每个角色重新启动,但这不是您想要的。你想把 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

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

【讨论】:

  • 感谢您的回答,我添加了解决方案,但是您的代码产生的结果与我的差不多
  • 你能指定什么时候
  • like question 可能有超过 3 个字母,就像我刚运行它时,结果得到了 Sha_g_Chi
  • 是的,你是对的,我编辑了我的答案。
【解决方案3】:

这是一个函数,它接受一个字符串和可选的数字来保存字母,所以 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-25
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 2012-10-26
    • 2018-05-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多