检查Python中子序列的单调性

时间:2016-08-02 14:08:36

标签: python subsequence

我希望能够找到单调减少子序列结束的索引,该子序列从列表的第一个索引开始,并且只按连续顺序下降。例如,我可能有一个如下所示的列表:

x = [89, 88, 88, 88, 88, 87, 88]我希望能够返回5,因为它是子序列[89, 88, 88, 88, 88, 87]的最后一个元素的索引,其中此子序列中的每个数字都是单调递减的并从列表的第一个索引89开始连续关闭。

比如说,我有一个如下所示的列表:x = [89, 87, 87, 86, 87]。我想返回0,因为它是唯一以第一个索引(89)开始并且连续单调递减的数字(即,列表中的下一个数字从第一个数字下降2)。或者,如果我有一个如下所示的列表:x = [89, 90, 89, 88],我想返回0,因为它是序列中唯一一个从列表的第一个索引单调递减的部分。

很抱歉解释困难。提前感谢您的帮助!

4 个答案:

答案 0 :(得分:0)

我不确定我是否完全理解这个问题,但请看一下:

def findseries(a):
    for i in xrange(len(a) - 1):
        if a[i+1] - a[i] not in [-1, 0]:
            return i
    return len(a) - 1

你基本上遍历列表。如果您检查的下一个元素完全小于当前或等于它,则我们知道当前将是该系列中的最后一个元素。

否则,我们继续下一个元素。

如果我们完成遍历整个列表而没有找到任何不匹配的元素,我们可以说列表的最后一个元素是该系列的最后一个元素,所以我们返回len(a) - 1 - 最后一个的索引元件。

答案 1 :(得分:0)

您可以使用python生成器表达式:

x = [89, 88, 88, 88, 88, 87, 88]
g = (i for i,(v,u) in enumerate(zip(x,x[1:])) if not (u+1==v or u==v))
next(g)
#output:
5

答案 2 :(得分:0)

如果您想使问题过于复杂,可以先创建一个函数,在迭代中生成连续条目对:

def consecutive_pairs(iterable):
    it = iter(iterable)
    first = next(it)
    for second in it:
        yield (first, second)
        first = second

然后,您可以检查每对中的差异是0还是1:

def last_decreasing_index(iterable):
    pairs = consecutive_pairs(iterable)
    for index, (first, second) in enumerate(pairs):
        if first - second not in (0, 1):
            return index
    return index + 1 # full sequence is monotonic

显然有更短的方法来实现相同的目标(参见其他答案)。

答案 3 :(得分:0)

如果[88,88,88]生成2:

,则此方法有效
def foo(it, n = 0):
    #print(it, n)
    try:
        monotonic = -1 < it[0] - it[1] < 2
        if monotonic:
            n = foo(it[1:], n + 1)
    except IndexError:
        pass
    return n

重构[88,88,88]输入产生0:

def foo(it, n = 0):
    print(it, n)
    try:
        difference = it[0] - it[1]
        if difference == 0 and n == 0:
            pass
        elif -1 < difference < 2:
            n = foo(it[1:], n + 1)
    except IndexError:
        pass
    return n