【问题标题】:Unexpected results while iterating through a string. Return values don't include all character replacements遍历字符串时出现意外结果。返回值不包括所有字符替换
【发布时间】:2020-07-07 04:03:23
【问题描述】:

所以我正在尝试解决 PyBites 平台上的一个问题,它要求您执行以下操作:

  • 任意字符串
  • 将其格式化为小写
  • 用 * 符号替换任何元音
  • 跟踪改变了多少元音

示例字符串 text = 'Hello World' 应返回以下元组:('h*ll* w*rld', 3),其中 3 表示已更改的总元音。

下面的代码包含一个应该处理所有列出的步骤的函数。我什至使用了赋值,以便我可以使用 .replace() 并输出更改后的字符:

from typing import Tuple

text = 'Hello World'

def strip_vowels(text: str) -> Tuple[str, int]:
    vowels = 'aeiou'
    count = 0
    text = text.lower().splitlines()
    for words in text:
        for char in words:
            for vowel in vowels:
                if char == vowel:
                    count += 1
                    result = words.replace(char, '*'), count                     
        return result
        

answer = strip_vowels(text)
print(answer)

我遇到的问题是,虽然我成功检查了字符串中的字符是否为元音,但返回值是关闭的:('hell* w*rld', 3) 我知道 replace() 会在每次迭代时检查元音,但它不会存储所有结果。

关于我应该采取哪些步骤的任何指导? 提前致谢。

【问题讨论】:

标签: python-3.x replace substring


【解决方案1】:

问题是在进行替换时使用了单词变量。变量一词的每次使用均指其原始循环变量形式。您需要使用替换创建的结果字符串。一个修复可能是在进入最顶层循环检查工作是否已被使用之前为结果分配一个 None 值:

result = None
for words in text:
.....

if result is None:
    result = words.replace(char, '*'), count   
else:
    result = result[0].replace(char, '*'), count

分割线的使用对我来说是模棱两可的,我没有看到它的必要性。 我认为创建可转换表会比使用的嵌套循环更有效

def strip_vowels(text: str) -> Tuple[str, int]:
    text = 'Hello World'
    inner, outer = "aeiou", "*"*5
    transtab = str.maketrans(inner, outer)

    text = text.translate(transtab)
    count = 0
    for letter in text:
        if letter == '*':
            count += 1
    return (text, count)

【讨论】:

    【解决方案2】:

    问题来了

    if char == vowel:
        count += 1
        result = words.replace(char, '*'), count  
    

    您替换了原始 text 的元音,而不将其保存到循环中。

    hello world这个词为例,

    |------|-------------|-------------|-------|
    | char | words       | result      | count |
    |------|-------------|-------------|-------|
    | h    | hello world | hello world |     0 |
    | e    | hello world | h*llo world |     1 | Replaced 'e', count + 1
    | l    | hello world | hello world |     1 |
    | l    | hello world | hello world |     1 |
    | o    | hello world | hell* w*rld |     2 | Replaced 'o', count + 1
    |      | hello world | hello world |     2 | 
    | w    | hello world | hello world |     2 |
    | o    | hello world | hell* w*rld |     3 | Replaced 'o', count + 1
    | r    | hello world | hello world |     3 |
    | l    | hello world | hello world |     3 |
    | d    | hello world | hello world |     3 |
    |------|-------------|-------------|-------|
    

    以下是您的代码的修改版本

    def strip_vowels(text: str) -> Tuple[str, int]:
        vowels = 'aeiou'
        count = 0
        text = text.lower().splitlines()
        for words in text:
            for char in words:
                for vowel in vowels:
                    if char == vowel:
                        count += 1
                        words = words.replace(char, '*')  # Modified
            return words, count                           # Modified
    
    print(strip_vowels('Hello World'))
    # Output:
    # ('H*ll* W*rld', 3)
    

    一个更整洁的版本应该是这样的

    def strip_vowels(text: str) -> Tuple[str, int]:
        vowels = 'aeiou'
        for vowel in vowels:
            text = text.replace(vowel.upper(), '*')
            text = text.replace(vowel.lower(), '*')
        return text, text.count('*')
    
    print(strip_vowels('Hello World'))
    # Output:
    # ('H*ll* W*rld', 3)
    

    【讨论】:

    • 这是一个很棒的答案!可视化我的实现如何遍历字符串的表格对我的理解至关重要。谢谢!!
    【解决方案3】:

    试试这个解决方案

    text = 'Hello World'
    
    def strip_vowels(text):
        newString = ''
        count = 0
        text = text.lower()
        for char in text:
            if(char in 'aeiou'):
                count += 1
                newString += '*'
            else:
                newString += char
            
        return newString, count
    
    answer = strip_vowels(text)
    print(answer)
    

    【讨论】:

    • 谢谢!我完全应该考虑使用“in”关键字。我知道一旦我有 3 个 for 循环,即使它是正确的,我的答案也会过于复杂。这是一个非常好的解决方案。
    • 一年欢迎好友
    猜你喜欢
    • 2012-10-18
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多