我認爲有,可以幫助您避免在循環結束重複碼三種一般方法。對於所有三個,我將使用一個與你自己稍有不同的示例問題,計算字符串中的單詞。這裏有一個「默認」的版本,像你的代碼,重複一些邏輯,在循環的末尾:
from collections import Counter
def countWords0(text):
counts = Counter()
word = ""
for c in text.lower():
if c not in "abcdefghijklmnopqrstuvwxyz'-":
if word:
counts[word] += 1
word = ""
else:
word += c
if word:
counts[word] += 1 # repeated code at end of loop
return counts
第一種方法是每一個字符後做(一些)的「序列結束」處理,如果序列在該字符之後立即結束,那麼簿記是正確的。在你的例子中,你可以消除你的「其他」條件,並且每次運行代碼。 (這是sergerg的答案。)
這可能並不容易一些各式各樣的檢查,但。爲了統計單詞,您需要添加一些額外的邏輯,以避免從您處理的「部分」子序列中累積雜音。這裏的代碼,不會說:
def countWords1(text):
counts = Counter()
word = ""
for c in text.lower():
if c not in "abcdefghijklmnopqrstuvwxyz'-":
word = ""
else:
if word:
counts[word] -= 1 # new extra logic
word += c
counts[word] += 1 # this line was moved from above
return counts + Counter() # more new stuff, to remove crufty zero-count items
第二個選擇是追加的警戒值,這將觸發行爲的期望「的序列結束」序列的末端。如果您需要避免哨兵污染您的數據(尤其是數字等),這可能會非常棘手。對於最長的連續子序列問題,可以添加任何不等於序列中最後一項的值。 None
可能是一個不錯的選擇。對於我的話計數例如,非文字字符(如換行符)會做:
def countWords2(text):
counts = Counter()
word = ""
for c in text.lower() + "\n": # NOTE: added a sentinel to the string!
if c not in "abcdefghijklmnopqrstuvwxyz'-":
if word:
counts[word] += 1
word = ""
else:
word += c
# no need to recheck at the end, since we know we ended with a space
return counts
第三種方法是更改代碼的結構,以避免循環訪問可能會意外結束的序列。您可以使用發電機來預處理序列,如在使用groupby
從itertools
其他的答案。 (當然,發電機的功能,如果你有他們自己寫的,可能有類似的問題。)
對於我的單詞統計例子,我可以使用正則表達式從re
模塊找到的話:
from re import finditer
def countWords3(text):
return Counter(match.group() for match in
finditer("[\w'-]+", text.lower()))
輸出,給予適當Python的文本時(這是所有四個版本countWords相同):
>>> text = """Well, there's egg and bacon; egg sausage and bacon;
egg and spam; egg bacon and spam; egg bacon sausage and spam;
spam bacon sausage and spam; spam egg spam spam bacon and spam;
spam sausage spam spam bacon spam tomato and spam;
spam spam spam egg and spam; spam spam spam spam spam spam
baked beans spam spam spam; or Lobster Thermidor a Crevette
with a mornay sauce served in a Provencale manner with shallots
and aubergines garnished with truffle pate, brandy and with a
fried egg on top and spam."""
>>> countWords0(text)
Counter({'spam': 28, 'and': 12, 'egg': 8, 'bacon': 7, 'sausage': 4, 'a': 4,
'with': 4, 'well': 1, 'lobster': 1, 'manner': 1, 'in': 1, 'top': 1,
'thermidor': 1, "there's": 1, 'truffle': 1, 'provencale': 1,
'sauce': 1, 'brandy': 1, 'pate': 1, 'shallots': 1, 'garnished': 1,
'tomato': 1, 'on': 1, 'baked': 1, 'aubergines': 1, 'mornay': 1,
'beans': 1, 'served': 1, 'fried': 1, 'crevette': 1, 'or': 1})
請使用'如果some_string:'檢查'some_string'不爲空 – jfs
'如果不是l'是多餘的。 'l'是個壞名字。 'most_reps'可以被稱爲'max_count'來清除與'count'的關係。 'i' - >'current','prv' - >'last' – jfs