关于python:Pythonic计算字符串列表中出现次数的方法

Pythonic way to count occurrences from a list in a string

从目标字符串的列表中查找字符串出现次数的最佳方法是什么?具体来说,我有一个清单:

1
2
3
4
5
6
7
8
9
10
string_list = [
   "foo",
   "bar",
   "baz"
]

target_string ="foo bar baz bar"

# Trying to write this function!
count = occurrence_counter(target_string) # should return 4

我想优化以最小化速度和内存使用,如果这有区别的话。就大小而言,我预计string_list最终可能包含几百个子串。


使用收集的另一种方法。计数器:

1
2
3
from collections import Counter
word_counts = Counter(target_string.split(' '))
total = sum(word_counts.get(w, 0)) for w in string_list)


这很管用!

1
2
def occurrence_counter(target_string):
    return sum(map(lambda x: x in string_list, target_string.split(' ')))

字符串被拆分为标记,然后每个标记都被转换为1(如果它在列表中),否则为0。求和函数最后求和这些值。

编辑:同时:

1
2
def occurrence_counter(target_string):
    return len(list(filter(lambda x: x in string_list, target_string.split(' '))))


这条Python3应该起作用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
In [4]: string_list = [
   ...:    "foo",
   ...:    "bar",
   ...:    "baz"
   ...: ]
   ...:
   ...: set_of_counted_word = set(string_list)
   ...:
   ...: def occurrence_counter(target_str, words_to_count=set_of_counted_word):
   ...:     return sum(1 for word in target_str.strip().split()
   ...:                if word in words_to_count)
   ...:
   ...:
   ...: for target_string in ("foo bar baz bar"," bip foo bap foo dib baz  "):
   ...:     print("Input: %r -> Count: %i" % (target_string, occurrence_counter(target_string)))
   ...:
   ...:
Input: 'foo bar baz bar' -> Count: 4
Input: ' bip foo bap foo dib baz   ' -> Count: 3

In [5]:


您可以使用trie将子字符串转换为regex模式(例如(?:ba[rz]|foo)并解析target_string

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import re
from trie import Trie

trie = Trie()

substrings = [
   "foo",
   "bar",
   "baz"
]
for substring in substrings:
    trie.add(substring)
print(trie.pattern())
# (?:ba[rz]|foo)

target_string ="foo bar baz bar"
print(len(re.findall(trie.pattern(), target_string)))
# 4

所需的图书馆在这里:trie.py

它应该比解析每个substring的整个target_string快得多,但它可能不会返回重叠子串的预期结果。返回["foo","bar","foobar"]"foobar"2

一个相关的问题是:"在python 3中加速数百万个regex替换":这里有一个关于集合的答案和一个带有trie regex的答案。


sumstring.count的组合:

1
2
def counter(s, lst)
    return sum(s.count(sub) for sub in lst)

这不会计算同一模式的重叠出现次数。


另一个解决方案:

1
2
3
def occurrence_counter(target_string, string_list):
    target_list = target_string.split(' ')
    return len([w for w in target_list if w in string_list])


您可以使用一个变量来存储一个正在运行的计数,如果您像这样迭代列表:

1
2
3
4
5
def occurence_counter(x):
    count = 0
    for y in x:
        count +=1
    return count


我不确定这是最毒气的方法,但你可以试试:

1
2
string_list_B = target_string.split("")
commonalities = set(string_list) - (set(string_list) - set(string_list_B))