首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >计算数组python中每个子串的个数

计算数组python中每个子串的个数
EN

Stack Overflow用户
提问于 2018-06-29 07:32:44
回答 3查看 137关注 0票数 3

例如[a_text, b_text, ab_text, a_text],我有一个string数组。我想要获取包含每个前缀的对象的数量,比如['a_', 'b_', 'ab_'],这样'a_'对象的数量就是2。

到目前为止,我一直在通过过滤数组来计算每个数组的值,例如num_a = len(filter(lambda x: x.startswith('a_'), array))。我不确定这是否比循环遍历所有字段并递增每个计数器更慢,因为我是在为每个要计数的前缀过滤数组。像filter()这样的函数比for循环快吗?对于这个场景,如果我使用For循环,我不需要构建过滤列表,这样可能会更快。

另外,也许我可以使用列表理解来代替filter,以使其更快?

EN

回答 3

Stack Overflow用户

发布于 2018-06-29 08:08:36

另一种方法是使用defaultdict()对象。您只需遍历整个列表一次,并在遇到时通过在下划线处拆分来计算每个前缀。您需要检查下划线是否存在,否则整个单词将被视为前缀(否则将无法区分'a''a_a')。

from collections import defaultdict

array = ['a_text', 'b_text', 'ab_text', 'a_text'] * 250000

def count_prefixes(arr):
    counts = defaultdict(int)
    for item in arr:
        if '_' in item:
            counts[item.split('_')[0] + '_'] += 1
    return counts

该逻辑类似于user3483203的答案,因为所有前缀都是在一次遍历中计算的。然而,调用正则表达式方法似乎比简单的字符串操作要慢一点。但我也不得不附和Michael的评论,因为即使是100万个项目,速度差异也是微不足道的。

from timeit import timeit

setup = """
from collections import Counter, defaultdict
import re

array = ['a_text', 'b_text', 'ab_text', 'a_text']

def with_defaultdict(arr):
    counts = defaultdict(int)
    for item in arr:
        if '_' in item:
            counts[item.split('_')[0] + '_'] += 1
    return counts

def with_counter(arr):
    matches = [re.match(r'^.*?_', i) for i in arr]
    return Counter([i.group() for i in matches if i])
"""

for method in ('with_defaultdict', 'with_counter'):
    print(timeit('{}(array)'.format(method), setup=setup, number=1))

计时结果:

0.4836089063341265
1.3238173544676142
票数 2
EN

Stack Overflow用户

发布于 2018-06-29 07:39:24

如果我理解您的要求,您似乎真的想使用正则表达式(Regex)。它们就是为这种模式匹配使用而构建的。我不知道Python,但我确实看到支持正则表达式,所以这是一个使用它们的问题。我使用this tool是因为它使得制作和测试您的正则表达式变得很容易。

票数 0
EN

Stack Overflow用户

发布于 2018-06-29 08:47:35

您还可以尝试使用str.partition()提取分隔符和分隔符之前的字符串,然后将这两个字符串连接起来形成前缀。然后,您只需检查此前缀是否存在于前缀集中,并使用collections.Counter()对其进行计数

from collections import Counter

arr = ['a_text', 'b_text', 'ab_text', 'a_text']

prefixes = {'a_', 'b_', 'ab_'}

counter = Counter()
for word in arr:
    before, delim, _ = word.partition('_')
    prefix = before + delim
    if prefix in prefixes:
        counter[prefix] += 1

print(counter)

以下哪项输出:

Counter({'a_': 2, 'b_': 1, 'ab_': 1})
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51092428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档