【问题标题】:Error while Trying To Print the First Occurrence of a repeating Character in a String using Python 3.6尝试使用 Python 3.6 打印字符串中第一次出现的重复字符时出错
【发布时间】:2018-03-26 08:12:33
【问题描述】:

我正在编写一个简单的程序,用*(asterisk) 替换字符串中的重复字符。但这里的事情是我可以打印字符串中重复字符的第一次出现,但不能打印其他出现。

例如, 如果我的输入Google,我的输出应该是Go**le

我可以用星号替换重复的字符,但找不到打印第一次出现的字符的方法。也就是说,我现在的输出是****le

看看我的 Python3 代码:

s = 'Google'
s = s.lower()
for i in s:
    if s.count(i)>1:
        s = s.replace(i,'*')
print(s)

有人可以建议我应该怎么做才能获得所需的输出吗?

【问题讨论】:

  • 好吧,目前你正在用大于 1 的计数替换所有内容。你需要做的是保持每个字母的运行计数,一旦它大于 1,用星号替换它。一本字典可以很好地解决这个问题。并不是说字符串是不可变的,因此每次删除/更改元素时,您都会创建一个新列表。 IOW 从头开始​​构建这个新字符串实际上会更快。
  • @PM2Ring No....我的程序认为字符不区分大小写,这就是为什么在我的代码的第二行中,我将字符串中的所有字符都转换为小写
  • @PM2Ring LOL,这不是作业!

标签: python string python-3.x printing


【解决方案1】:

使用列表压缩怎么样?当从另一个列表构造一个列表时(这就是您在这里所做的,因为我们将字符串视为列表),列表理解是一个很好的工具:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

inputstring = 'Google'.lower()
outputstring = ''.join(
    [char if inputstring.find(char, 0, index) == -1 else '*'
    for index, char in enumerate(inputstring)])
print(outputstring)

这导致go**le

希望这会有所帮助!

编辑使用“*”代替“#”作为替换字符)

【讨论】:

  • 它从头开始扫描直到当前索引,而不是当前索引。当然,我没有考虑性能,但我猜这比添加查找集使用更少的内存,而且我也认为它比正则表达式更有效。然而,这些都是毫无根据的说法。 :-)
【解决方案2】:

这是我的方法:

首先,您需要找到第 n 次出现的字符。然后,您可以使用此 sn-p 替换其他匹配项:

s = s[:position] + '*' + s[position+1:]

完整示例代码:

def find_nth(haystack, needle, n):
    start = haystack.find(needle)
    while start >= 0 and n > 1:
        start = haystack.find(needle, start+len(needle))
        n -= 1
    return start

s = 'Google'
s_lower = s.lower()

for c in s_lower:
    if s_lower.count(c) > 1:
        position = find_nth(s_lower, c, 2)
        s = s[:position] + '*' + s[position+1:]
print(s)

可运行链接:https://repl.it/Mc4U/4


正则表达式方法:

import re

s = 'Google'

s_lower = s.lower()

for c in s_lower:
    if s_lower.count(c) > 1:
        position = [m.start() for m in re.finditer(c, s_lower)][1]
        s = s[:position] + '*' + s[position+1:]

print(s)

可运行链接:https://repl.it/Mc4U/3

【讨论】:

    【解决方案3】:

    replace 将替换所有出现的字符。您需要关注您已经看过的字符,如果它们被重复替换只是这个字符(在特定索引处)。

    字符串不支持索引分配,所以我们可以建立一个新的列表来代表新的字符串,然后''.join()它。

    使用Set,您可以关注您已经看过的内容。

    看起来像这样:

    s = 'Google'
    seen = set()
    new_string = []
    
    for c in s:
        if c.lower() in seen:
            new_string.append('*')
        else:
            new_string.append(c)
            seen.add(c.lower())
    
    new_string = ''.join(new_string)
    print(new_string)
    Go**le
    

    【讨论】:

    • @Vinny 这个工作,在某种程度上,当我给 print(new_string) 时,它给了 ['g', 'o', '*', '*', 'l', 'e'] 。但所需的输出是Go**le
    • @PM2Ring 你是对的。我已更新解决方案以提供该解决方案
    • @SteffiKeranRaniJ new_string 是一个列表,您需要先join() 它才能成为一个字符串。我更新了代码,所以new_string 现在将打印预期的字符串
    • 我刚刚注意到并想通了,这确实是一个更好的方法
    • @SteffiKeranRaniJ 查看新答案。更好,因为我删除了不必要的zip
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多