2012-02-29 87 views
3

我有一個單詞列表,可以說:[「foo」,「bar」,「baz」]和一個可能出現這些單詞的大字符串。計算幾個特定詞的出現次數

我現在使用列表中的每個單詞「string」.count(「word」)方法。這工作正常,但似乎相當低效。對於添加到列表中的每個額外的單詞,整個字符串必須在額外的時間內迭代。

他們是否有更好的方法來做到這一點,或者我應該實現一種自定義方法,它一次迭代大字符串,檢查每個字符是否已經到達列表中的一個單詞?

要明確:

  • 我想每個字出現在列表中的號碼。每次
  • 在搜索的字符串是不同的,由大約10000個字符
  • 單詞列表是恆定
  • 中的單詞列表中的單詞可以包含空格
+1

用空格分隔單詞嗎?如果是,那麼從集合中導入計數器' – DrTyrsa 2012-02-29 12:01:41

+1

「似乎效率很低。對於每個添加到列表中的額外單詞」...「要清楚:單詞列表是恆定的。 – wim 2012-02-29 12:09:29

回答

7

爲您的單詞製作一個dict型頻率表,然後遍歷字符串中的單詞。

vocab = ["foo", "bar", "baz"] 
s = "foo bar baz bar quux foo bla bla" 

wordcount = dict((x,0) for x in vocab) 
for w in re.findall(r"\w+", s): 
    if w in wordcount: 
     wordcount[w] += 1 

編輯:如果在列表中的「字」包含空格,可以改爲建立一個RE了出來:

from collections import Counter 

vocab = ["foo bar", "baz"] 
r = re.compile("|".join(r"\b%s\b" % w for w in vocab)) 
wordcount = Counter(re.findall(r, s)) 

說明:此建立從詞彙的RE r'\bfoo bar\b|\bbaz\b'findall然後找到列表['baz', 'foo bar']Counter(Python 2.7+)計算其中每個不同元素的出現次數。 小心您的單詞列表不應包含特殊的字符,如​​。

+0

(+1)您的編輯似乎正是OP正在尋找的內容。 – 2012-02-29 14:17:41

+0

你救了我的一天! – 2018-01-07 04:07:21

1

是多久你字符串,我明白,它不會不斷變化,因爲你的字符串列表是?

一個好主意是迭代字符串中的單詞併爲單詞添加詞典並增加每個單詞的計數。有了這個。然後,您可以在字典中的列表中查找單詞,並輸出它是出現次數的值。

3

。假定的話需要單獨(即,要算的話,通過str.split()製造)發現:

編輯:按照意見提出,計數器是一個很好的選擇,在這裏:

from collections import Counter 

def count_many(needles, haystack): 
    count = Counter(haystack.split()) 
    return {key: count[key] for key in count if key in needles} 

,哪個跑得像這樣:

count_many(["foo", "bar", "baz"], "testing somefoothing foo bar baz bax foo foo foo bar bar test bar test") 
{'baz': 1, 'foo': 4, 'bar': 4} 

注意的是Python < = 2.6,你將需要使用return dict((key, count[key]) for key in count if key in needles)由於T(?)他缺乏對詞典的理解。

當然,另一種選擇是簡單地返回整個Counter對象,並且只在需要時獲取所需的值,因爲根據具體情況,獲取額外值可能不成問題。

老答案:

from collections import defaultdict 

def count_many(needles, haystack): 
    count = defaultdict(int) 
    for word in haystack.split(): 
     if word in needles: 
      count[word] += 1 
    return count 

導致:

count_many(["foo", "bar", "baz"], "testing somefoothing foo bar baz bax foo foo foo bar bar test bar test") 
defaultdict(<class 'int'>, {'baz': 1, 'foo': 4, 'bar': 4}) 

如果您大大對象得到一個defaultdict回來(你不應該,因爲它的功能完全一樣的字典當訪問),那麼你可以做return dict(count)而不是獲得一個正常的字典。

相關問題