简体   繁体   中英

Counting sequential occurrences in a list and

I have 3 lists as follows:

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']

I would like to count sequential occurrences of 'H' in each list and produce the following table showing the frequencies of these 'H' sequences:

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

I know that doing the following gives me the frequnecies of a sequence in a list:

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

But am in need of an elegant way to take this further over the remaining lists and ensuring that a '0' is placed for unobserved lengths.

You can use collections.Counter to create a frequency dict from a generator expression that outputs the lengths of sequences generated by itertools.groupby , and then iterate through a range of possible lengths to output the frequencies from the said dict, with 0 as a default value in absence of a frequency.

Using L1 as an example:

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)])

This outputs:

[0, 1, 0, 1, 0]

You can use itertools.groupby with collections.Counter :

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)

Output:

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

This might work :

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

For a sample L4 = ['T', 'T'] where there is no 'H' item in list, it returns [0] . For L1 it returns [2, 0, 4, 0] . For L2 it returns [2, 0, 4, 0, 1, 0, 3, 0] . For L3 it returns [1, 0, 2] .

请尝试max([len(x) for x in ''.join(y).split('T')])其中y是你的列表。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM