【问题标题】:Whats wrong with my python pangram function我的 python pangram 函数有什么问题
【发布时间】:2020-06-09 18:08:00
【问题描述】:

它是一个检查字符串是否为Pangram 的函数 所以如果 str1 == 'the quick brown fox jumps over the lazy dog' 函数将返回 True,因为字符串包含字母表中的每个字母。

import string

def ispangram(str1, alphabet=string.ascii_lowercase):
    for char in set(alphabet): 
        if char in str1:
            return True
        else:
            return False

【问题讨论】:

  • 欢迎来到stackoverflow!为了帮助我们回答您的问题,请提供更多详细信息,包括您的代码的预期输出是什么以及您将得到什么。
  • 在第一次到达return 行后,它不只是结束函数(返回True/False)吗?
  • ifreturn True 翻转到循环外,否则您只会为输入字符串中出现的第一个字符返回True。
  • 这能回答你的问题吗? How to check if string is a pangram?

标签: python function pangram


【解决方案1】:

只要在str1 中找到第一个字母,该函数就会返回True

你需要做的是:

def ispangram(str1, alphabet=string.ascii_lowercase):
    for char in set(alphabet): 
        if char not in str1:
            return False
    return True

这样,只有当char 不在str1 中并且只有在发现str1 中存在所有字符后,该函数才返回False,它才返回True

您可能想使用str1.lower(),因为您只检查小写字母。

【讨论】:

  • 哦,这更有意义。谢谢!
  • setfor char in set(alphabet): 中为您做什么?如果不将alphabet 转换为set,它不应该也能正常工作吗?
  • for char in alphabet: 也可以正常工作,但当一个字符在alphabet 中多次出现时可能不会那么快。此外,我正在编辑原始代码并仅指出导致问题的部分,而没有进行可能混淆实际修复的其他编辑。
【解决方案2】:

在不确切知道您的函数应该做什么的情况下,我怀疑问题是您在循环的第一次迭代中返回 TrueFalse,因此只分析了第一个字母。试试这个:

import string

def ispangram(str1, alphabet=string.ascii_lowercase):
    for char in set(alphabet): 
        if char not in str1:
            return False

    return True

【讨论】:

  • set for char in set(alphabet): 中为您做什么?如果不将alphabet 转换为set,它不应该也能正常工作吗?
  • 它仍然可以工作,set() 完成的唯一事情是,在字母表中有重复项的情况下,这些重复项只需要评估一次,这在某些情况下可能需要更多计算昂贵然后生成集合
【解决方案3】:

正如其他地方所指出的,您的逻辑颠倒并且缩进不正确。但是您的设计很好,因为它自然会忽略不是字母的字符。我会添加一些针对混合大小写的防御并稍微简化它:

from string import ascii_lowercase as alphabet

def ispangram(string):
    string = string.lower()

    for character in alphabet:
        if character not in string:
            return False

    return True


print(ispangram('Watch "Jeopardy!", Alex Trebek\'s fun TV quiz game.'))

【讨论】:

  • @AnnZen,首先,简化为“单线”并不是所有 Python 的目标。第二,你搞砸了。通过包含[...] 括号,您将其设置为list 理解,需要在调用all() 之前完成——因此,第一次错过时的快捷方式会消失,因此它比我的效率低原来的。如果您省略了[...] 括号,那么它将是一个生成器表达式,并且会正确地使用快捷方式,在第一次未命中时返回False
  • 你的函数可以缩短为一个班轮: def ispangram(string): return all(character in string.lower() for character in alphabet)
  • 我同意,从来没有说过它是 :) 不过,我认为使用 all() 会更 Pythonic。感谢您对生成器的指点。
  • @AnnZen,您的一个班轮在每次迭代中调用string.lower(),而它只需要小写一次。
【解决方案4】:

这是与您不同的方法:

import string

def ispangram(str1, alphabet=string.ascii_lowercase):
    return len(set(l.lower() for l in str1 if l.lower() in alphabet)) == len(alphabet)

print(ispangram("I am very tired, but I will keep programming to pass the quiz!"))

输出:

False

【讨论】:

  • 您不需要TrueFalse 的显式返回,只需return len(set(...)) == len(alphabet)。函数不需要知道答案,只需要知道调用者。
【解决方案5】:

你不需要set(alphapet),你可以直接迭代alphabet

如果您在该函数将返回 False 的情况下,该函数将退出而不执行以下行,因此在完成 for 循环后不返回 false 那么我们有 pangram 情况,因此该函数会直接返回True

import string

def ispangram(str1, alphabet=string.ascii_lowercase):
    for char in alphabet: 
        if char not in str1:
            return False         
    return True

str1 = 'the quick brown fox jumps over the lazy dog'
print(ispangram('Hello')) #False
print(ispangram(str1)) #True

但是,我们可以使用all() 将函数缩短为

def ispangram(str1, alphabet=string.ascii_lowercase):
    return all([char in  str1 for char in alphabet])

【讨论】:

    【解决方案6】:

    如果在您的字符串中找到任何字母字符,您的函数将返回 True。那是你想要的吗?它遍历set(alphabet) 中的汽车,如果其中任何一个在您的字符串if char in str1 中,则返回True。这对您的目标似乎不是很有用。您可能需要更复杂的逻辑,检查字符的顺序,如果您正在查看回文,则字符串在反转时是否相同等。希望这有助于指导您!

    【讨论】:

      【解决方案7】:

      考虑输入"abc"。当您的函数遍历字母表中的字母时,它以"a" 开头,发现它在输入字符串中,然后返回True。您需要检查以确保 所有 字母表中的字母都在输入字符串中

      【讨论】:

        【解决方案8】:

        您的函数在检查alphabet 的第一个字符后直接返回,而不管str1 中的字符是否存在。事实上,你的函数只是检查你的字符串中是否有字母表中的某个字符。

        你打算做的是:

        import string
        
        def ispangram(str1, alphabet=string.ascii_lowercase):
            for char in set(alphabet): 
                if char not in str1:
                    return False
            else:
                return True
        

        然而,一个更简单的解决方案就是:

        def ispangram(str1, alphabet=string.ascii_lowercase)
            return set(str1) >= set(alphabet)
        

        【讨论】:

        • 你似乎和我有同样的想法,但我放弃了 set 选项,因为通常 pangrams 是句子包含的不仅仅是 ascii 字符,比如空格或标点符号,这使得 set 不匹配
        • 需要做类似return set(string.ascii_lowercase) == set([char for char in str1 if char in string.ascii_lowercase])的事情
        • 或者直接使用>=
        • 更好的主意
        • 你能解释一下 set(str1) >= set(alphabet): 部分吗?
        猜你喜欢
        • 1970-01-01
        • 2021-04-11
        • 2015-09-30
        • 2017-10-07
        • 2013-07-12
        • 1970-01-01
        • 2017-08-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多