2014-09-10 130 views
1

问:pangram是一个句子,它至少包含一次英文字母的所有字母,例如:快速棕色狐狸跳过懒狗。你的任务是写一个函数来检查一个句子,看它是否是一个句子。在Python上需要帮助

我所拥有的是:

def isPangram(s): 
    alphabetList = 'abcdefghijklmnopqrstuvwxyz' 
    alphabetCount = 0 
    if len(s) < 26: 
     return False 
    else: 
     s = re.sub('[^a-zA-Z]','',s).lower() 
       for i in range(len(alphabetList)): 
      if alphabetList[i] in s: 
       alphabetCount = alphabetCount + 1 
     if alphabetCount == 26: 
      return True 
     else: 
      return False 

然而,当我尝试例如S = [“敏捷的棕色狐狸跳过懒狗”],结果是假,这是不对的。它应该是真正的B/C它包含所有26个字母。任何人都可以帮我修复代码吗?非常感谢!!!

+0

第一件事 - 'LEN(S)'可以评价为'1'如果s是一个列表。只需将它传递给字符串 – karthikr 2014-09-10 15:56:45

+0

请注意''alphabetList'预定义为'string.ascii_lowercase'。 – chepner 2014-09-10 16:03:30

回答

2

将句子中的字母缩小为一个集合更简单,然后验证该集合是所有字母的集合。

def isPangram(s): 
    alphabet = set('abcdefghijklmnopqrstuvwxyz') 
    s = re.sub('[^a-zA-Z]', '', s) 
    sentence = set(s.lower()) 
    return sentence == alphabet 

assert isPangram("The quick brown fox jumped over the lazy dog") 
+1

这里不需要使用正则表达式 - 只需将字符串转换为小写字母,然后执行一组交集并查看字母表与字母表的交集是否与字母表相同。 '(set(s.lower())&alphabet_set)== alphabet_set' – 2014-09-10 16:00:24

+1

True;我原本尽可能使用用户的代码,并没有删除它。等同地,您可以检查“alphabet - sentence”是否为空。 – chepner 2014-09-10 16:01:28

3

问题是你传递的是字符串列表而不是列表。只需传入"The quick brown fox jumps over the lazy dog"而没有括号,你的代码就可以工作。

你的代码也是不必要的复杂性(和误缩进启动):

if alphabetCount == 26: 
    return True 
else: 
    return False 

是太复杂 - alphabetCount == 26已经是真或假的!所以你可以简单地写

return alphabetCount == 26 

此外,你迭代输入字符串与索引变量。这是完全没有必要的,只是遍历输入字符串,像这样:

for c in alphabetList: 
    if c in s: 
     alphabetCount += + 1 

在上面 - 而现在已经造成的错误,因为代码会失败,否则 - 为len(s) < 26检查完全是多余的,只是去掉它。

字母表也已经嵌入到Python中,它被称为string.ascii_lowercase。所以你不需要自己写!

这就是说,你的算法仍然非常慢 - 你迭代了26次!为什么不干脆写

import string 
def isPangram(s): 
    return set(s.lower()) >= set(string.ascii_lowercase) 

+0

为什么你使用lambda来定义一个函数来将它分配给一个名字? lambda的全部和唯一一点是该函数是匿名的,可以用在表达式中;你会抛弃这两个好处并获得所有缺点(例如,回溯中的名称将是''而不是'isPangram')。 PEP 8更深入地解释了为什么你不应该这样做。 – abarnert 2014-09-10 17:06:10

+0

但除此之外,很好的解释了OP的代码有什么问题以及它可以改进的所有方法。 – abarnert 2014-09-10 17:06:36

+0

@abarnert你说得对,lambda只是出于打高尔夫球的目的。固定。 – phihag 2014-09-10 19:46:44

1

我会使用套:

def isPangram(s): 
    alphabetset = set('abcdefghijklmnopqrstuvwxyz') 
    set_string = set(s.lower()) 
    return set_string.issuperset(alphabetset) 

用法:

>>> isPangram('aabc') 
False 
>>> isPangram('aabcdefghijklmnopqrstuvwxyz') 
True 
>>> isPangram('aabcdefghijklmnopqrstuvwxyz J:L FSDJ f09823740235') 
True 
0

如果s是阵列()S = [”快速的棕色狐狸跳过懒狗“]你只能得到一个len()= 1,那么如果len(s) < 26:总是返回False

def isPangram(s): 

    alphabetList = 'abcdefghijklmnopqrstuvwxyz' 
    alphabetCount = 0 
    if len(s) < 26: 
     print "False 1" 
    else: 
     s = re.sub('[^a-zA-Z]','',s).lower() 
     for i in range(len(alphabetList)): 
      if alphabetList[i] in s: 
       alphabetCount = alphabetCount + 1 
     if alphabetCount == 26: 
      print "True" 
     else: 
      print "False" 
a=isPangram("The quick brown fox jumps over the lazy dog") 
+0

你是什么意思“如果s是数组()”?你期待它是一个'array.array('c')'或什么的?即使是这样,它会如何不同于列表(看起来像)或其他任何东西? – abarnert 2014-09-10 22:41:18

+0

总是我认为这个“s”是数组,或者你可以尝试与类型进行比较, – 2015-09-10 19:08:13

0

请行之后删除else语句:

if alphabetCount == 26: 
    return True 

,因为它是把代码放到else条件为I = 0本身,因为它是只取一个字母计数。

import re 
def isPangram(s): 
    alphabetList = 'abcdefghijklmnopqrstuvwxyz' 
    alphabetCount = 0 
    if len(s) < 26: 
     print('lenth is short') 
     return False 
    else: 
     s = re.sub('[^a-zA-Z]','',s).lower() 
     print(s) 
     for i in range(len(alphabetList)): 
      if alphabetList[i] in s: 
       print(alphabetList[i]) 
       print("The string is pangram2") 
       alphabetCount = alphabetCount + 1 
       print(alphabetCount) 
       if alphabetCount >= 26: 
        print("The string is pangram") 
        return True 

现在的代码运行正常

我看到