更多pythonic方法过滤列表中的稳定值

时间:2017-01-23 10:08:20

标签: python list functional-programming filtering purely-functional

我写了一个函数,它允许我运行一个列表,将值与前辈进行比较,并断言列表变为" stable"对于一定数量的条目。 列表中的值表示可能达到或未达到稳定点的信号。 我想出了这个:

def unstableFor(points, maxStable):
    count = 0;
    prev = points[0]
    for i in range(1, len(points)):
        if points[i] == prev:
            count = count + 1
        else:
            count = 0
            prev = points[i]
        if count >= maxStable:
            return i
    return len(points) - 1

然后调用者使用返回的值来删除列表的最后部分。

它完成了它的工作,然而,我对它看起来多么笨重感到十分不满。你能想到一种更加pythonic,可能是纯功能的方式来执行这种过滤操作吗?

3 个答案:

答案 0 :(得分:2)

使用枚举和压缩:

def unstableFor (points, threshold):
    for i, (a, b) in enumerate(zip(points, points[1:])):
        count = count + 1 if a == b else 0
        if count >= threshold:
            return i
    return i

答案 1 :(得分:1)

这是一个功能性方法的草图。这有点神秘。实际上,我可能会使用您的方法(使用enumerate作为惯用方式而不是range(len(x)))。无论如何,假设max_stable是3:

>>> from itertools import groupby
>>> grouped = groupby(enumerate(x), lambda i_e: i_e[1])
>>> gen = (g for g in map(lambda e: list(e[1]), grouped) if len(g) >= 3)
>>> run = next(gen)
>>> run[2][0]
10

在这里清理:

>>> from operator import itemgetter
>>> from itertools import islice
>>> def unstable_for(points, max_stable):
...     grouped = groupby(enumerate(points), itemgetter(1))
...     gen = (g for g in (tuple(gg) for _, gg in grouped) if len(g) >= max_stable)
...     run = tuple(islice(gen,1))
...     if len(run) == 0:
...         return len(points) - 1
...     else:
...         return run[0][max_stable - 1][0]
...
>>> x
[1, 2, 3, 3, 4, 5, 6, 7, 8, 8, 8, 8, 8, 9]
>>> unstable_for(x, 3)
10
>>> unstable_for(x, 2)
3
>>> unstable_for(x, 1)
0
>>> unstable_for(x, 20)
13
>>>

不是很优雅。再说一遍,我会选择必要的解决方案。也许某人有更优雅的功能解决方案。

答案 2 :(得分:1)

您的代码对我来说很好看:它易于阅读和理解。我会删除一些重复,使它看起来像:

def unstableFor(points, maxStable):
    prev = None  # assuming None is not member of points
    for i, point in enumerate(points):
        if point == prev:
            count = count + 1
        else:
            count = 0
            prev = point
        if count >= maxStable:
            break
    return i