从序列创建所有固定长度的不连续子序列

2024-06-16 09:12:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有如下顺序:

seq = "SDLKFJSOIDHFSODIF"

我想为这个做所有长度为5的不连续子序列。因为有5个可能的阅读框架,所以我想要一个由5个列表组成的列表,如下所示:

[["SDLKF", "JSOID", "HFSOD"], ["DLKFJ", "SOIDH", FSODI"], ...]

所有字符不会出现在每个列表中,对于本例,第5个列表只有两个条目。这没关系。你知道吗

我怎样才能做一个函数,把它推广到所有可能的子序列长度?你知道吗

谢谢! 杰克


Tags: 框架列表顺序条目序列字符seq本例
2条回答

通过嵌套列表理解:

>>> [[seq[i: i + 5] for i in range(j, len(seq), 5) if i + 5 <= len(seq)] for j in range(5)]
[['SDLKF', 'JSOID', 'HFSOD'],
 ['DLKFJ', 'SOIDH', 'FSODI'],
 ['LKFJS', 'OIDHF', 'SODIF'],
 ['KFJSO', 'IDHFS'],
 ['FJSOI', 'DHFSO']]

虽然单列表理解是更好的答案,但这里有一个^{}1方法。你知道吗

给定的

import itertools as it

import more_itertools as mit


seq = "SDLKFJSOIDHFSODIF"
size = 5

代码

windows = it.islice(mit.stagger(seq, offsets=range(len(seq)), longest=True), size)
[["".join(x) for x in mit.sliced(w, size) if None not in x and len(x) == size] for w in windows]

输出

[['SDLKF', 'JSOID', 'HFSOD'],
 ['DLKFJ', 'SOIDH', 'FSODI'],
 ['LKFJS', 'OIDHF', 'SODIF'],
 ['KFJSO', 'IDHFS'],
 ['FJSOI', 'DHFSO']]

细节

目标:制作序列的几个滑动窗口,并将它们分成。你知道吗

在第一个列表理解中,结果是收缩滑动windows。为了演示,下面是一个完整级联结果的示例:

>>> windows = mit.stagger(seq, offsets=range(len(seq)), longest=True)
>>> ["".join(filter(None, w)) for w in windows]
['SDLKFJSOIDHFSODIF',
'DLKFJSOIDHFSODIF',
'LKFJSOIDHFSODIF',
'KFJSOIDHFSODIF',
'FJSOIDHFSODIF',
'JSOIDHFSODIF',
'SOIDHFSODIF',
'OIDHFSODIF',
'IDHFSODIF',
'DHFSODIF',
'HFSODIF',
'FSODIF',
'SODIF',
'ODIF',
'DIF',
'IF',
'F']

注意,对于每个窗口,左侧滑动,而右侧固定。换句话说,每次迭代的窗口大小都会缩小1。这些缩小窗口是通过more_itertools.stagger中的offsets参数实现的(有关详细信息,请参见the docs)。由于该过程重复,因此通过^{}只选择给定size的第一个窗口。你知道吗

第二种理解是将这些窗口分成一组size,丢弃无效的块(< size或包含fillvalue None,这是more_itertools.stagger中的默认值)。你知道吗

1more_itertools是通过^{}安装的第三方库。

相关问题 更多 >