Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pythonic:查找特定长度的所有连续子序列_Python_Algorithm_List - Fatal编程技术网

Pythonic:查找特定长度的所有连续子序列

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

我有一个整数列表,我想在这个列表中找到所有长度为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(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:]

这里有一个更通用的解决方案,适用于任意输入可比性(不仅仅是序列):

  • 在输入中查找连续的子字符串,如
    6、7、8、9
    。其依据是:

    该解决方案的关键是使用以下公式生成的范围进行差分: enumerate()使连续整数都出现在同一组中 (跑)

  • +
    zip
    允许在子字符串k-wise上迭代——的泛化

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