如何循环在Python中的二维列表之间进行操作?

How to operate between 2D lists in Python in a loop?

所以基本上我创建了一个基于用户输入的房屋坐标 (x,y) 的程序,它会根据曼哈顿平均距离在 R2 中分配一个最佳位置来建造警察局。显然,越少越好。 这是我已经写的:

L=[]
K=[]
Kx=[]
Ky=[]
NoHouses=int(input("How many houses are there? : "))

for i in range(1,NoHouses+1):
      plot1 = input("coordinate(x, y) for house" +str(i)+" :").split()
      plot1 = [int(i) for i in plot1]
      K.append(plot1)
      Kx.append(plot1[0])
      Ky.append(plot1[1])
      Ky.sort()
      Kx.sort()
for i in range(Kx[0],Kx[-1]+1):
    for j in range(Ky[0],Ky[-1]+1):
        L.append([i,j])
        print("House Coordinates: ",(K))
print("List of x coordinate: ",(Kx))
print("List of y coordinates: ",(Ky))
print("Possible police station coordinates: ",(L))

基本上我尝试做的是找到从可能的警察局坐标到用户给定的房屋的曼哈顿距离。所以最后我应该留下一个列表“D”,它有 len(L)==len(D) (num of police station coordinates== num of manhattan distances) ,然后我会排序并找到最小值。我面临的问题是为每个可能的警察局坐标找到曼哈顿距离。我究竟做错了什么?虽然我预计输出是 len(L) 它似乎是随机的。下面是我试过的:

D=[]
K=[[1,2],[2,2]] #test case
L=[[1,1],[2,6]]  #testcase
def manhattan_distance(point1,point2):
    return sum(abs(value1 - value2) for value1, value2 in zip(point1,point2))
for i in range(len(L)):
    for j in range(len(K)):
       x1=L[i]
       x2=K[j]
       D.append(manhattan_distance(x1,x2))
print(manhattan_distance(x1,x2))
print(D)


        

您附加的代码适用于 1 个坐标对。对于多个坐标对,您一直附加到 D 而不是为坐标的新值创建新的 D2。对于坐标对的多个值,我建议如下:

D=[]
K=[[1,2], [2,9]] #test case
L=[[1,1],[2,6], [4,5]]  #testcase
def manhattan_distance(point1,point2):
    return sum(abs(value1 - value2) for value1, value2 in zip(point1,point2))

D = {}
for ii, k in enumerate(K):
    temp = []
    for l in L:
       temp.append(manhattan_distance(l,k))
    D[ii] = temp
print(D)  # {0: [1, 5, 6], 1: [9, 3, 6]} 

这将创建一个字典,其中包含 K 中每个坐标对的列表。

但是,您可以在没有 for 循环的情况下执行相同的操作,从而显着改善大 L 值的运行时间。为此,我们将使用 numpy 包。这个想法是使用矢量计算而不是 运行 for 循环一次计算所有内容。使用与上述相同的数据,我们可以执行以下操作:

L = np.array(L)
K = np.array(K)

现在 L 是一个包含所有坐标的 (?,2) 形状数组,而 K 是一个 (2,) 1 维数组。通过如下执行减法:

temp = L - K

发生的事情是 numpyL 的所有行广播 K,同时对所有行执行减法。然后,对列维度执行绝对和求和将得到所需的 D 值:

D = {}
for ii, k in enumerate(K):
    temp = np.sum(np.abs(L - k), axis=1)
    D[ii] = list(temp)
print(D)

如果您想要列表类型,您可以将 numpy array 转换回列表。

运行 两个版本的 L 大小为 (100000, 2) 使用 %%timeit 导致:

  1. 使用 for 循环方法,花费了 282 ms ± 6.71 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
  2. 使用numpy,花了17.4 ms ± 646 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

快一个数量级。