在列表中计算连续出现的次数

3

我有以下3个列表:

L1 = ['H', 'H', 'T', 'T', 'T', 'H', 'H', 'H', 'H', 'T']
L2 = ['H', 'H', 'T', 'T', 'T', 'H', 'H', 'H', 'H', 'T' , 'T', 'H, 'T', 'T', 'T', 'H', 'H', 'H', 'T']
L3 = ['H', 'T', 'H', 'H']

我希望能够统计每个列表中'H'字符出现的连续次数,并生成以下表格以显示这些'H'序列的频率:
Length | L1 | L2 | L3
----------------------
1         0    1   1
2         1    1   1   
3         0    1   0
4         1    1   0
5         0    0   0

我知道以下操作可以给出列表中一个序列的频率:

from itertools import groupby
[len(list(g[1])) for g in groupby(L1) if g[0]=='H']

[2, 4]

但我需要一种优雅的方法来进一步处理剩下的列表,并确保未观察到的长度处放置'0'。

4个回答

3
您可以使用collections.Counter从一个生成器表达式创建一个频率字典,该生成器表达式输出由itertools.groupby生成的序列长度,然后通过迭代可能的长度范围来输出该字典中的频率,如果不存在该频率,则默认值为0。
L1作为示例:
from itertools import groupby
from collections import Counter
counts = Counter(sum(1 for _ in g) for k, g in groupby(L1) if k == 'H')
print([counts[length] for length in range(1, 6)])

这将输出:

[0, 1, 0, 1, 0]

2
您可以使用collections.Counteritertools.groupby来实现:
import itertools as it, collections as _col
def scores(l):
  return _col.Counter([len(list(b)) for a, b in it.groupby(l, key=lambda x:x == 'H') if a])

L1 = ['H', 'H', 'T', 'T', 'T', 'H', 'H', 'H', 'H', 'T']
L2 = ['H', 'H', 'T', 'T', 'T', 'H', 'H', 'H', 'H', 'T' , 'T', 'H', 'T', 'T', 'T', 'H', 'H', 'H', 'T']
L3 = ['H', 'T', 'H', 'H']
d = {'L1':scores(L1), 'L2':scores(L2), 'L3':scores(L3)}
r = '\n'.join([f'Length | {" | ".join(d.keys())} ', '-'*20]+[f'{i}          {"   ".join(str(b.get(i, 0)) for b in d.values())}' for i in range(1, 6)])
print(r)

输出:

Length | L1 | L2 | L3 
--------------------
1          0   1   1
2          1   1   1
3          0   1   0
4          1   1   0
5          0   0   0

0
请尝试使用 y 列表,运行以下代码:max([len(x) for x in ''.join(y).split('T')])

0

这可能有效:

from itertools import groupby
a = [len(list(v)) if k=='H' and v else 0 for k,v in groupby(''.join(L1))]

对于样例L4 = ['T', 'T'],其中列表中没有'H'项,它返回[0]。 对于L1,它返回[2, 0, 4, 0]。 对于L2,它返回[2, 0, 4, 0, 1, 0, 3, 0]。 对于L3,它返回[1, 0, 2]


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接