2014-09-10 176 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 

現在的代碼運行正常

我看到