Python 3:测试一行中的连续数字

Python 3: test for contiguous numbers in one line

我有一个运行良好的算法,但我希望以另一种方式实现它以获得个人满意度。

简而言之:我有一些数组 obj_level,它是一个布尔掩码,指示对象所在的坐标,所以类似于

 obj_level = [ 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 , 1, 1 ]

我想识别物体的底部和顶部。

我首先通过生成一个包含对象非零索引的数组来做到这一点,obj_idx。如果数组不为空,则第一个值附加到 base.

然后我循环测试索引+1的值是否等于obj_idx中的下一个对象。如果是,没有找到边,继续。

否则,我找到了一条边,所以我追加到 basetop。我可以推断在找到的边上同时存在顶部和底部,因为在 obj_idx 中有更多值,因为我正在针对 obj_idx[i+1].

进行测试

最后,我将最后一个值附加到 top,因为如果有底部,对象必须有顶部。

    base = []
    top = []
    obj_idx = np.flatnonzero(obj_level)
    if obj_idx.size > 0:
        base . append(obj_idx[0])
        for i,idx in enumerate(obj_idx[:-1]):
            if idx+1 == obj_idx[i+1]:
                continue
            else:
                top.append(idx)
                base.append(obj_idx[i+1])
        top.append(obj_idx[-1])

我想用更少的行来完成这项工作。类似于:

    base = [
           idx + 1 == obj_idx[i+1] or idx+1
           for i,idx in enumerate(obj_idx[:-1])
           ]
    top =  [
           (idx+1 == obj_idx[i+1] or idx
           for i,idx in enumerate(obj_idx[:-1])
           ]
    np.insert(base,0,obj_idx[0])
    np.insert(top,-1,obj_idx[-1])

但我最终得到了一个类似 [True, True, 3, True, True]

的混合数组

有没有比从混合数组中提取整数更简单的方法?

您可以只使用列表理解中的 'if' 子句,如此处 if/else in a list comprehension 所述,以过滤源可迭代对象。类似的东西(我避免使用 numpy 连接值只是为了组成一个单行,但当然它不会改变任何东西):

base = [obj_idx[0]] + [
   obj_idx[i+1] for i in range(1, len(obj_idx)-1) if (obj_idx[i+1] != obj_idx[i] + 1)
   ]
top = [
   obj_idx[i] for i in range(1, len(obj_idx)-1) if (obj_idx[i+1] != obj_idx[i] + 1)
   ] + [obj_idx[-1]]