在 python 中,我有一个轮廓列表(每个都包含 x、y、w 和 h 整数),我需要以某种方式遍历列表并检查当前的 x + w 是否比最后一个 x + w 小大于 3(即 1 或 2)删除当前的,否则继续。
我现在有这个:
contours_v2 = [[551, 0, 2, 1], [491, 0, 1, 1], [484, 0, 6, 1], [482, 0, 1, 1], [480, 0, 1, 1], [400, 0, 6, 1], [321, 0, 6, 1], [319, 0, 1, 1], [238, 0, 1, 1], [234, 0, 3, 1], [229, 0, 4, 1], [227, 0, 1, 1], [225, 0, 1, 1], [223, 0, 1, 1], [142, 0, 1, 1], [132, 0, 6, 1], [130, 0, 1, 1], [0, 0, 7, 1]]
last_x_w = contours_v2[0][0] + contours_v2[0][2] # Initialize with the first contour's x + w value
i = 1 # Start with the second contour
while i < len(contours_v2):
current_x_w = contours_v2[i][0] + contours_v2[i][2]
if abs(last_x_w - current_x_w) < 4:
contours_v2.pop(i)
else:
last_x_w = current_x_w
i += 1
我需要一些东西:
如果我将
i += 1
移动到 else
语句中,结果列表将是(输入列表是我提供的示例):
# As you can see, the item didn't pop and should have popped is
# the one with x = 229, its next one is x = 227
# contours_v2
[[551, 0, 2, 1], [491, 0, 1, 1], [482, 0, 1, 1], [400, 0, 6, 1], [321, 0, 6, 1], [319, 0, 1, 1], [238, 0, 1, 1], [229, 0, 4, 1], [227, 0, 1, 1], [223, 0, 1, 1], [142, 0, 1, 1], [132, 0, 6, 1], [130, 0, 1, 1], [0, 0, 7, 1]]
编写更短(但不一定更快)代码的一种方法是
from functools import reduce
contours_v2 = [[551, 0, 2, 1], [491, 0, 1, 1], [484, 0, 6, 1], [482, 0, 1, 1], [480, 0, 1, 1], [400, 0, 6, 1], [321, 0, 6, 1], [319, 0, 1, 1], [238, 0, 1, 1], [234, 0, 3, 1], [229, 0, 4, 1], [227, 0, 1, 1], [225, 0, 1, 1], [223, 0, 1, 1], [142, 0, 1, 1], [132, 0, 6, 1], [130, 0, 1, 1], [0, 0, 7, 1]]
def x_w(c):
return c[0] + c[2]
r = reduce(lambda x, y: x if abs(x_w(x[-1]) - x_w(y)) < 4 else x + [y],
contours_v2[1:], [contours_v2[0]])
print(r)
reduce
的初始值设定项是一个包含 contours_v2
第一项的列表,然后对于其余的每一项,检查其与列表最后一项的距离,并通过 if 表达式返回未修改的列表返回 lambda 或附加了新项目的新列表。
代码做了一些可能比传统循环慢的事情,因为它可能必须为相同的
c[0] + c[2]
重复计算c
并且它使用等同于x = x + [y]
的东西比x.append(y)
慢。