Pythonic:查找特定长度的所有连续子序列
我有一个整数列表,我想在这个列表中找到所有长度为n的连续子序列。例如:Pythonic:查找特定长度的所有连续子序列,python,algorithm,list,Python,Algorithm,List,我有一个整数列表,我想在这个列表中找到所有长度为n的连续子序列。例如: >>> int_list = [1,4,6,7,8,9] >>> conseq_sequences(int_list, length=3) [[6,7,8], [7,8,9]] 我能想到的最好办法是: def conseq_sequences(self, li, length): return [li[n:n+length] for n in xrange
>>> int_list = [1,4,6,7,8,9]
>>> conseq_sequences(int_list, length=3)
[[6,7,8], [7,8,9]]
我能想到的最好办法是:
def conseq_sequences(self, li, length):
return [li[n:n+length]
for n in xrange(len(li)-length+1)
if li[n:n+length] == range(li[n], li[n]+length)]
这不是非常可读。有什么可读的pythonic方法吗?使用和
没有进口
def conseq_sequences(li, length):
res = zip(*(li[i:] for i in xrange(length)))
final = []
for ele in res:
if all(x == y+1 for x, y in zip(ele[1:], ele)):
final.append(ele)
return final
可转化为列表理解:
def conseq_sequences(li, length):
res = zip(*(li[i:] for i in xrange(length)))
return [ ele for ele in res if all(x == y+1 for x, y in zip(ele[1:], ele))]
一种解决办法如下:
import numpy # used diff function from numpy, but if not present, than some lambda or other helper function could be used.
def conseq_sequences(li, length):
return [int_list[i:i+length] for i in range(0, len(int_list)) if sum(numpy.diff(int_list[i:i+length]))==length-1]
def diff(l):
'''For example, when l=[1,2,3] than return is [1,1]'''
return [x - l[i - 1] for i, x in enumerate(l)][1:]
基本上,首先,我从列表中获取给定长度的连续子列表,然后检查它们元素的差异之和是否等于length-1
请注意,如果元素是连续的,它们的差异将相加为长度-1
,例如,对于子列表[5,6,7]
,其元素的差异为[1,1]
,其总和为2
但老实说,我不确定这个解决方案是否比你的更清晰或更具Python风格
如果您没有numpy
,则diff
函数可以简单地定义如下:
import numpy # used diff function from numpy, but if not present, than some lambda or other helper function could be used.
def conseq_sequences(li, length):
return [int_list[i:i+length] for i in range(0, len(int_list)) if sum(numpy.diff(int_list[i:i+length]))==length-1]
def diff(l):
'''For example, when l=[1,2,3] than return is [1,1]'''
return [x - l[i - 1] for i, x in enumerate(l)][1:]
这里有一个更通用的解决方案,适用于任意输入可比性(不仅仅是序列):
- 在输入中查找连续的子字符串,如
。其依据是: 该解决方案的关键是使用以下公式生成的范围进行差分: enumerate()使连续整数都出现在同一组中 (跑)6、7、8、9
- +
允许在子字符串k-wise上迭代——的泛化zip
来自next(islice(迭代器,n,n),None)
print(*consecutive_subseq([1,4,6,7,8,9], 3))
# -> (6, 7, 8) (7, 8, 9)
该代码使用Python 3语法,如果需要,可以对Python 2进行修改
另请参见,这与OP在输入上的代码不同,如
[4,1,5,2,6]
@user2357112,暂时脑死亡,我完全忽略了连续部分。这不尊重连续性约束:conseq_序列([1,4,2,7,3])
给出结果[1,2,3],[2,3,4]
。然而,列表[1,2,3]
不是我们初始列表的子列表,对于[2,3,4]
而言,数字在初始列表中以不同的顺序出现,并且也不是必需的。对不起,我忘记了这个条件。现在代码也处理了这个条件。我假设列表的长度将大于3,这很容易检查。就使用内置库而言,这对我来说是最优雅的。将不得不查找您提供的链接,以便完全了解正在发生的事情。不过,可读性仍然相当困难!您可以假定int_列表已排序。
def condition (tup):
if tup[0] + 1 == tup[1] and tup[1] + 1 == tup[2] :
return True
return False
def conseq_sequence(li):
return [x for x in map(None, iter(li), iter(li[1:]), iter(li[2:])) if condition(x)]