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 |
我想优化以最小化速度和内存使用,如果这有区别的话。就大小而言,我预计
使用收集的另一种方法。计数器:
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模式(例如
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 |
。
所需的图书馆在这里:
它应该比解析每个
一个相关的问题是:"在python 3中加速数百万个regex替换":这里有一个关于集合的答案和一个带有trie regex的答案。
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)) |