Python列表仅在等于n个前驱者时保持值

Fre*_*sky 7 python

我有一个信号列表(代表连续的测量):

signals = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0]
Run Code Online (Sandbox Code Playgroud)

我认为信号只有在等于前面的n个测量值时才有效.

例如.如果我们只考虑2个测试验证(n=2),第一次信号从0变为1我们认为它仍然是0但是下一个测量,如果它再次为1则我们认为它仍然有效并使其成为1.然后我们需要2个测量0再次将其变为0等等...这里的信号为0和1以简化,但在我的应用中它们可以是其他整数.

期望的输出:

# For n = 2:
valid_s = [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0]

# For n = 3:
valid_s = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0]

# For n = 4:
valid_s = [0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0]
Run Code Online (Sandbox Code Playgroud)

我正在寻找一种pythonesque单行方式,但似乎无法找到所需的输出.我尝试了一些事情:

S = signals

# For n = 2
[S[i] if S[i] == S[i-1] else S[i-2] for i, _ in enumerate(S)]
# gives [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0]

# For n = 3
[S[i] if S[i] == S[i-1] == S[i-2] else S[i-3] for i, _ in enumerate(S)]
# gives [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0]
Run Code Online (Sandbox Code Playgroud)

编辑:numpy如果因为它已经导入它更容易,我愿意接受.

tob*_*s_k 5

我不认为有一个好方法可以使这个单线/列表理解.虽然您可以使用all列表的一部分来查看该值是否与n之前的值相同,但我没有看到确定哪个应该是最后一个有效值的好方法,如果不是.

相反,你可以使用一个古老的"多行"循环:

signals = [0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0]
n = 3

last_valid = 0
current = None
repeated = 0
res = []
for s in signals:
    if s == current:
        repeated += 1
    else:
        repeated = 1
        current = s
    if repeated >= n:
        last_valid = s
    res.append(last_valid)
Run Code Online (Sandbox Code Playgroud)

之后,res[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0]


或者,稍微短一些,使用itertools.groupby; 结果是一样的:

last_valid = 0
res = []
for k, g in itertools.groupby(signals):
    m = len(list(g))
    if m >= n:
        res.extend([last_valid] * (n-1) + [k] * (m-n+1))
        last_valid = k
    else:
        res.extend([last_valid] * m)
Run Code Online (Sandbox Code Playgroud)

  • 附录:和往常一样,如果你想要一个单行解决方案,那就让它成为一个功能.;-) (2认同)