2012-08-24 71 views
4

在英語中每個角色都有發生的百分比,這些百分比:在列表中的值,蟒蛇

A  B  C  D  E  F  G  H  I 
.0817 .0149 .0278 .0425 .1270 .0223 .0202 .0609 .0697 
J  K  L  M  N  O  P  Q  R 
.0015 .0077 .0402 .0241 .0675 .0751 .0193 .0009 .0599 
S  T  U  V  W  X  Y  Z 
.0633 .0906 .0276 .0098 .0236 .0015 .0197 .0007 

稱爲letterGoodness名單預定義爲:

letterGoodness = [.0817,.0149,.0278,.0425,.1270,.0223,.0202,... 

我需要找到一個字符串的「優點」。例如,'I EAT'的優點是:.0697 + .1270 + .0817 + .0906 = .369。這是一個更大問題的一部分,但我需要解決這個問題來解決這個大問題。我開始是這樣的:

def goodness(message): 
    for i in L: 
    for j in i: 

所以它將足以找出如何獲得任何字符的出現百分比。你可以幫我嗎? 該字符串只包含大寫字母和空格。

+4

您有一個長度爲26的數組。字符串中的每個字符都有一個ascii數字。編寫一個方法將ascii編號轉換爲正確的數組索引。然後,您可以簡單地迭代字符串,將O(n)中的優美值相加。 新編輯:如果你的字符串只有大寫字母,那麼是的,一個字典將刪除我描述的散列函數的需要。 –

回答

12

letterGoodness是一本字典更好,那麼你可以這樣做:

sum(letterGoodness.get(c,0) for c in yourstring.upper()) 
#            #^.upper for defensive programming 

letterGoodness從列表轉換爲dictonary,你可以這樣做:

import string 
letterGoodness = dict(zip(string.ascii_uppercase,letterGoodness)) 

如果你保證只能有大寫字母和空格,你可以這樣做:

letterGoodness = dict(zip(string.ascii_uppercase,letterGoodness)) 
letterGoodness[' '] = 0 
sum(letterGoodness[c] for c in yourstring) 

但是性能這裏的收益可能非常小,所以我會贊成上面更強大的版本。


如果你堅持不讓letterGoodness作爲一個列表(我不建議這),您可以使用內置的ord獲得指數(由cwallenpoole指出):

ordA = ord('A') 
sum(letterGoodness[ord(c)-ordA] for c in yourstring if c in string.ascii_uppercase) 

我現在懶得timeit,但是你可能想要定義一個臨時集來保存string.ascii_uppercase - 它可能會使你的函數運行得更快一些(取決於如何優化str.__contains__set.__contains__進行比較):

ordA = ord('A') 
big_letters = set(string.ascii_uppercase) 
sum(letterGoodness[ord(c)-ordA] for c in yourstring.upper() if c in big_letters) 
+1

但是不要忘記丟棄非字母字符。 –

+0

啊,我看到你今天也在瀏覽python的問題。擊敗我8秒和代碼啓動。我可能會在明天再回來:D – chucksmash

+5

爲了避免非字母問題,我會使用'letterGoodness.get(i.upper(),0)'而不是進行成員測試。 – DSM

1

您最好使用字典數據結構。

編輯:這不是我的原始代碼,而是沿DSM建議更新的代碼。

import string 

num_vals = [.0817, .0149, .0278, .0425, .1270, .0223, .0202, .0609, .0697 , .0015, .0077, 
      .0402, .0241, .0675, .0751, .0193, .0009, .0599, .0633, .0906, .0276, .0098, 
      .0236, .0015, .0197, .0007] 

letterGoodness = {letter : value for letter,value in map(None, string.ascii_uppercase, num_vals)} 

def goodness(message): 
    string_goodness = 0 
    for letter in message: 
     letter = letter.upper() 
     if letter in letterGoodness.keys(): 
      string_goodness += letterGoodness[letter] 
    return string_goodness 

print goodness("I eat") 

使用您所提供的測試案例:

print goodness("I eat") 

產生輸出:

.369 

有一點要注意 - 作爲建設在這裏做需要Python的2.7+的字典。 Python 2.6+和dict()構造函數可以完成同樣的事情。

+2

我不能把我的手指放在什麼數量的重複線之前,我會將重複的摘要消除,但我相信,二十六個是在它之上。我認爲大多數Python程序員會做更多的事情,比如@mgilson做的,並且在這方面看起來有點可疑。 – DSM

+0

有效評論。我使用編輯器中的查找/替換抽象了這些重複內容,但它對代碼輸出沒有影響 - 結果不夠優雅。 – chucksmash

+2

'map(None,...)'最好寫成'zip(...)'。 – Marcin