使用模式阈值识别单词列表中的模式

Identify patterns within list of words with pattern threshold

正在研究 Python 中的模式识别功能,假设 return 带有计数器的模式数组

让我们想象一个字符串列表:

m = ['ABA','ABB', 'ABC','BCA','BCB','BCC','ABBC', 'ABBA', 'ABBC']

在高层,我想回复的是:

Pattern | Count
----------------
   AB   |   6
  ABB   |   4
   BC   |   3
----------------

问题:据我所知,模式以 2 个字符开头并且是每个字符串值的前导字符(即 XXZZZ、XXXZZZ(其中 XX 是我正在寻找的模式))。我希望能够将模式的最小长度参数化为函数的输入,以优化 运行 时间。

PS。列表中的每一项都是一个单词。

我的问题是我需要从阈值开始对每个字母进行迭代,但我被困在那里了。 我更喜欢使用 startswith('AB')

首先,让我们定义您的字符串:

>>> m = ['ABA','ABB', 'ABC','BCA','BCB','BCC','ABBC', 'ABBA', 'ABBC']

现在,让我们计算一下所有长度为 2 或 3 的前导字符串:

>>> from collections import Counter
>>> c = Counter([s[:2] for s in m] + [s[:3] for s in m if len(s)>=3])

为了与您的 table 进行比较,以下是三个最常见的前导字符串:

>>> c.most_common(3)
Out[15]: [('AB', 6), ('ABB', 4), ('BC', 3)]

更新

包括所有键,最大长度为 len(max(m, key=len))-1:

>>> n = len(max(m, key=len))
>>> c = Counter(s[:i] for s in m for i in range(2, min(n, 1+len(s))))

附加测试

为了证明我们可以正确处理更长的字符串,让我们考虑不同的输入:

>>> m = ['ab', 'abc', 'abcdef']
>>> n = len(max(m, key=len))
>>> c = Counter(s[:i] for s in m for i in range(2, min(n, 1+len(s))))
>>> c.most_common()
[('ab', 3), ('abc', 2), ('abcd', 1), ('abcde', 1)]

使用collections.Counter

counter = collections.Counter()
min_length = 2
max_length = len(max(m, key=len))
for length in range(min_length, max_length):
    counter.update(word[:length] for word in m if len(word) >= length)

您可以使用函数accumulate()生成累积字符串,使用函数islice()获取最小长度的字符串:

from itertools import accumulate, islice
from collections import Counter

m = ['ABA','ABB', 'ABC','BCA','BCB','BCC','ABBC', 'ABBA', 'ABBC']

c = Counter()
for i in map(accumulate, m):
    c.update(islice(i, 1, None)) # get strings with a minimal length of 2

print(c.most_common(3))
# [('AB', 6), ('ABB', 4), ('BC', 3)]