2011-07-09 157 views
0

輸入是一個字符串,其思想是隻計算字母A-Z,並按出現次數按字母順序打印。列表理解中的Rm重複

像往常一樣我一直在這'直到我得到了一個工作結果,但現在試圖優化它,以便更好地理解Python的做事方式。

def string_lower_as_list(string): 
    """ 
     >>> string_lower_as_list('a bC') 
     ['a', ' ', 'b', 'c'] 
    """ 
    return list(string.lower()) 

from sys import argv 

letters = [letter for letter in string_lower_as_list(argv[1]) 
      if ord(letter) < 124 and ord(letter) > 96] 

uniques = sorted(set(letters)) 

for let in uniques: 
    print let, letters.count(let) 
  1. 如何刪除ORD(字母)的列表中理解的重複?
  2. 在這種情況下使用Dictionary或Tuple會有什麼好處,如果是這樣,怎麼辦?

編輯 應該說,Python 2.7版在Win32

回答

2

您可以直接比較的信件,你實際上只需要比較小寫字母

letters = [letter for letter in string_lower_as_list(argv[1]) 
      if "a" <= letter <= "z"] 

但更好的辦法是使用一個字典來計算值。每當你打電話時,letters.count必須遍歷列表。但是你已經遍歷這個列表來篩選出正確的字符,爲什麼不在同一時間對它們進行計數呢?

letters = {} 

for letter in string_lower_as_list(argv[1]): 
    if "a" <= letter <= "z": 
     letters[letter] = letters.get(letter, 0) + 1 

for letter in sorted(letters): 
    print letter, letters[letter] 

編輯:正如有人說,你不必將字符串轉換到一個列表。你可以直接迭代它:for letter in argv[1].lower()

+0

呀,誰需要'ord'反正:)順便說一句,在OP的代碼的範圍實際上是「A」到'{'包含在內。 –

+0

啊,所以..我沒有意識到我可以做「一個」<=字母,發現這個令人困惑的範圍('a','z')不起作用。 – Cups

+0

@Cups:說實話,我也發現它困惑,'range('a','z')'不起作用...... –

2

如何刪除列表理解中ord(letter)的重複?

你可以使用一個非Python特有的,有點神奇的成語,它在其他語言中不起作用:if 96 < ord(letter) < 124

在這種情況下使用字典或元組會有什麼好處,如果是這樣,怎麼辦?

您可以嘗試使用Python 2.7中添加的collections.Counter類。

P.S.您不需要將字符串轉換爲列表,以便在列表理解中迭代它。任何迭代都可以工作,並且字符串是可迭代的。

P.S. 2.要獲得該房產'這封信是字母',而不是降低和比較範圍,只需使用str.isalpha。 Unicode對象提供了相同的方法,它允許相同的代碼在外語中正常工作,而不必知道哪些字符是「字母」。 :)

+0

非常感謝。 – Cups

+0

collections.Counter crikey看起來很強大 - 必須從2.6升級活動服務器以充分利用,特別是在NLP類型的工作中。 – Cups

1

您不必將字符串轉換爲列表,字符串是可迭代:

letters = {} 
for letter in argv[1].lower(): 
    if "a" <= letter <= "z": 
     letters[letter] = letters.get(letter, 0) + 1 

for letter in sorted(letters.keys()): 
    print letter, letters[letter]