2014-02-27 28 views
0

我編寫了這個程序來計算一組點的三維距離。在Python中聯合列表的列表

points = [(472765.09, 6191522.78, 13.0), (472764.82, 6191524.09, 9.0), (472763.8, 6191525.68, 8.0), (472764.07, 6191524.39, 16.0)] 


def dist3d((x0, y0, z0), (x1, y1, z1)): 
    return math.sqrt((x0-x1)**2+(y0-y1)**2+(z0-z1)**2) 

def dist_3d(obs): 
    dist_list = list() 
    while len(obs) != 1: 
     obs_g = [(obs[0], x) for x in obs[1:]] 
     dist_list.append([dist3d(obs_g[i][0], obs_g[i][1]) for i in xrange(len(obs_g))]) 
     obs.pop(0) 
    return dist_list 

結果是距離列表的列表:

test = dist_3d(points) 
print test 
[[4.217700795331081, 5.922339064664832, 3.554222840244929], [2.1374049685457694, 7.046453008421205], [8.107835716151763]] 

的結果,我希望有如下:

[4.217700795331081, 5.922339064664832, 3.554222840244929, 2.1374049685457694, 7.046453008421205, 8.107835716151763] 

PS:該代碼是不是因爲優化「 points「函數返回後的列表只有一個元素

points = [(472765.09, 6191522.78, 13.0), (472764.82, 6191524.09, 9.0), (472763.8, 6191525.68, 8.0), (472764.07, 6191524.39, 16.0)] 
test = dist_3d(points) 
points 
[(472764.07, 6191524.39, 16.0)] 

回答

1

要解決的第一個問題,在這條線使用list.extend

dist_list.append([dist3d(obs_g[i][0], obs_g[i][1]) for i in xrange(len(obs_g))]) 

爲:

  ###### 
dist_list.extend([dist3d(obs_g[i][0], obs_g[i][1]) for i in xrange(len(obs_g))]) 
      ###### 

Here是爲什麼,這將有助於演示。


你的第二個問題來自這行:

obs.pop(0) 

因爲obspoints均引用同一個列表對象,調用obs.pop是一樣直接調用points.pop。換句話說,每次執行該行時,都會從points中彈出一個項目。最後,這將導致points只包含一個項目。

要解決這個問題,使points淺表副本內dist_3d

copy = obs[:] 

然後,調用pop的副本。這樣做會使points不受影響。


下面是修改後的代碼樣式:

import math 

points = [(472765.09, 6191522.78, 13.0), (472764.82, 6191524.09, 9.0), (472763.8, 6191525.68, 8.0), (472764.07, 6191524.39, 16.0)] 

def dist3d((x0, y0, z0), (x1, y1, z1)): 
    return math.sqrt((x0-x1)**2+(y0-y1)**2+(z0-z1)**2) 

def dist_3d(obs): 
    dist_list = list() 
    copy = obs[:] 
    while len(copy) != 1: 
     obs_g = [(copy[0], x) for x in copy[1:]] 
     dist_list.extend([dist3d(obs_g[i][0], obs_g[i][1]) for i in xrange(len(obs_g))]) 
     copy.pop(0) 
    return dist_list 

這裏是一個運行示例:

>>> import math 
>>> points = [(472765.09, 6191522.78, 13.0), (472764.82, 6191524.09, 9.0), (472763.8, 6191525.68, 8.0), (472764.07, 6191524.39, 16.0)] 
>>> def dist3d((x0, y0, z0), (x1, y1, z1)): 
...  return math.sqrt((x0-x1)**2+(y0-y1)**2+(z0-z1)**2) 
... 
>>> def dist_3d(obs): 
...  dist_list = list() 
...  copy = obs[:] 
...  while len(copy) != 1: 
...   obs_g = [(copy[0], x) for x in copy[1:]] 
...   dist_list.extend([dist3d(obs_g[i][0], obs_g[i][1]) for i in xrange(len(obs_g))]) 
...   copy.pop(0) 
...  return dist_list 
... 
>>> test = dist_3d(points) 
>>> print test 
[4.217700795331081, 5.922339064664832, 3.554222840244929, 2.1374049685457694, 7.046453008421205, 8.107835716151763] 
>>> print points 
[(472765.09, 6191522.78, 13.0), (472764.82, 6191524.09, 9.0), (472763.8, 6191525.68, 8.0), (472764.07, 6191524.39, 16.0)] 
>>> 
+0

感謝ICodez。測試中的一個元素的問題依然存在。查看帖子中的更新 –

0
import itertools 

def dist_3d(obs): 
    dist_list = list() 
    while len(obs) != 1: 
     obs_g = [(obs[0], x) for x in obs[1:]] 
     dist_list.append([dist3d(obs_g[i][0], obs_g[i][1]) for i in xrange(len(obs_g))]) 
     obs.pop(0) 
    return list(itertools.chain(*dist_list))