我有这样的名单:
[0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]
,我想得到一个列表,该列表描述每个元素到最接近的非零值的距离。在这种情况下,它将是:
[3, 2, 1, 0, 1, 0, 0, 1, 2, 2, 1, 0]
答案 0 :(得分:2)
使用无穷大初始化距离列表。
遍历列表,并跟踪到最后看到的非零值的距离。如果该距离小于列表中存储的距离(当前为无穷大),请更新distances
列表。
重复步骤2,但向后遍历列表。
代码:
lst = [0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]
# initialize the distances to infinity
distances = [float('inf')] * len(lst)
# loop over the list twice, once from the left and once from the right
for indices in [range(len(lst)), range(len(lst)-1, -1, -1)]:
# keep track of the distance to the last seen non-zero value
distance = float('inf')
for i in indices:
# when we find a non-zero value, set the distance to 0
if lst[i] != 0:
distance = 0
distances[i] = min(distances[i], distance)
# with each step we take, increase the distance by 1
distance += 1
print(distances)
# output: [3, 2, 1, 0, 1, 0, 0, 1, 2, 2, 1, 0]
答案 1 :(得分:0)
def f(lst):
ans = [0 for x in range(len(lst))]
last_non_zero = -len(lst)
last_edited = -1
for i in range(len(lst)):
if lst[i] != 1:
for j in range(last_edited+1, i):
ans[j] = min(abs(i-j), abs(j-last_non_zero))
last_edited = i
last_non_zero = i
return ans
时间复杂度为O(n)。
答案 2 :(得分:0)
import numpy as np
test = [0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]
non_zero_idx = np.array([idx for idx, x in enumerate(test) if x is not 0])
这时,您拥有所有非零值的idx。您所要做的就是取两者之差与每个值的值IDx之间的最小值。
distances = [min(abs(idx-np.array(non_zero_idx))) for idx, x in enumerate(test)]
distances
[3,2,1,0,1,0,0,1,2,2,1,0]
答案 3 :(得分:0)
您可以使用两个列表推导来组合在列表中前进和后退的距离:
s = [0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1]
forward = [s[i:].index(1) if x!=1 else 0 for i, x in enumerate(s)]
s_r = s[::-1]
backward = [s_r[i:].index(1) if 1 in s_r[i:] else 0 if x==1 else float('inf') for i, x in enumerate(s_r)][::-1]
然后,您可以将两个结果列表压缩在一起,并在每个索引处采用最小距离:
final = [min(i,j) for i, j in zip(forward, backward)]
收益:
[3, 2, 1, 0, 1, 0, 0, 1, 2, 2, 1, 0]