在Python中迭代2d列表,两个位置之间的距离

时间:2014-03-03 20:06:38

标签: python list iteration distance

我有一个二维清单(清单清单),其中我在美国有几个地点及其相关的纬度和经度。以下是前几个城市的一个例子:

"Millersville","CA",35.303850,-118.457860    #(city 1)
"Millersville","IL",39.451150,-89.158140     #(city 2)
"Millersville","IN",39.853100,‐86.091650     #(city 3)
"Millersville","MD",39.059550,-76.648020     #(city 4)

我正在尝试设置一个迭代,它将通过纬度和经度计算城市1和城市2之间的距离,然后将该值保存到loc1_loc2,然后继续计算城市1和城市之间的距离3,将值保存到loc1_loc3等等。它需要对所有可能的组合执行此操作并保存每个值。这就是我在修补的东西,但我根本无法让它经历迭代:

for i in range(len(places)):
    dlat = math.radians(float(places[i][2])-float(places[0][2]))
    dlon = math.radians(float(places[i][3])-float(places[0][3]))
    a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(float(places[0][2]))) \
        * math.cos(math.radians(float(places[i][2]))) * math.sin(dlon/2) * math.sin(dlon/2)
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
    d = radius * c
    loc0_loc0 = d * 0.621371

print loc0_loc0

我做错了什么?我如何让这个迭代设置遍历我所有的城市(根据我使用的列表中的未知数量)并计算每个城市之间的所有可能距离?

我很感激帮助!

2 个答案:

答案 0 :(得分:1)

您的代码很难阅读,这会掩盖您尝试做的事情。有四个位置,您需要(4 x(4-1))= 6个距离,但随着地点数量的增加,这个数字会迅速增长。在这里我发现并计算完整的4 x 4距离矩阵 - 显然我正在做一些你可以消除的冗余工作。

您的下载使得理解正在发生的事情非常困难,因此我在for循环中使用解包分配以避免它并将数据的每个元素绑定到名称。

import math
places = [
    ["Millersville", "CA", 35.303850, -118.457860],    #(city 1)
    ["Millersville", "IL", 39.451150, -89.158140 ],    #(city 2)
    ["Millersville", "IN", 39.853100, -86.091650 ],     #(city 3)
    ["Millersville", "MD", 39.059550, -76.648020 ]      #(city 4)
]
# One of the minus signs was weird
radius = 6371 # Mean radius in Km
distances = []
for nameA, stateA, latA, longA in places:
    dists_row = []
    for nameB, stateB, latB, longB in places:
        dlat = math.radians(latA-latB)
        dlon = math.radians(longA-longB)
        a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(latA)) \
            * math.cos(math.radians(latB)) * math.sin(dlon/2) * math.sin(dlon/2)
        c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
        d = radius * c
        distance = d * 0.621371
        dists_row.append(distance)
    distances.append(dists_row)

for row in distances:
    print(row)

打印出来

[0.0, 1626.6140655454842, 1789.8845362720158, 2295.8829666956335]
[1626.6140655454842, 0.0, 165.46706149552824, 669.3166714199295]
[1789.8845362720158, 165.46706149552824, 0.0, 506.5281329453448]
[2295.8829666956335, 669.3166714199295, 506.5281329453448, 0.0]

这是非常对称的,令人放心的是在对角线上有零,这意味着我可能没有把你的公式搞砸,因为我正在重写它们。这是一个打印结果而不是将它们存储在矩阵中的版本。在这个中我只计算一次距离。

radius = 6371 # Mean radius in Km
for stnum, (nameA, stateA, latA, longA) in enumerate(places):
    for nameB, stateB, latB, longB in places[stnum+1:]:
        dlat = math.radians(latA-latB)
        dlon = math.radians(longA-longB)
        a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(latA)) \
            * math.cos(math.radians(latB)) * math.sin(dlon/2) * math.sin(dlon/2)
        c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
        d = radius * c
        distance = d * 0.621371
        print(nameA, stateA, "to", nameB, stateB, "is", distance, "miles")

输出

Millersville CA to Millersville IL is 1626.6140655454842 miles
Millersville CA to Millersville IN is 1789.8845362720158 miles
Millersville CA to Millersville MD is 2295.8829666956335 miles
Millersville IL to Millersville IN is 165.46706149552824 miles
Millersville IL to Millersville MD is 669.3166714199295 miles
Millersville IN to Millersville MD is 506.5281329453448 miles

答案 1 :(得分:0)

这样的事可能有用......

resultDict = {}
for startCity in places:
    for endCity in places:
        startLocation = startCity[0] + ' ' + startCity[1]
        endLocation = endCity[0] + ' ' + endCity[1]
        resultLocations = [startLocation, endLocation]
        resultId = ','.join(resultLocations.sort())

        if startLocation == endLocation or resultId in resultDict:
            continue

        dlat = math.radians(float(startCity[2])-float(endCity[2]))
        dlon = math.radians(float(startCity[3])-float(endCity[3]))
        a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(float(endCity[2]))) \
            * math.cos(math.radians(float(startCity[2]))) * math.sin(dlon/2) * math.sin(dlon/2)
        c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
        d = radius * c
        resultDict[resultId] = d * 0.621371

print resultDict