【问题标题】:How to union a list of lists?如何合并列表列表?
【发布时间】:2014-02-27 23:11:29
【问题描述】:

我编写了这个程序来计算一组点的 3d 距离。

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]

P.S.:代码没有优化,因为函数返回后的“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)]

【问题讨论】:

    标签: python list optimization coding-style


    【解决方案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 仅包含一项。

    要解决此问题,请在dist_3d 内制作points 的浅表副本:

    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)]
    >>>
    

    【讨论】:

    • 感谢 ICodez。测试中的一个元素的问题仍然存在。查看帖子中的更新
    【解决方案2】:
    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))
    

    【讨论】:

      猜你喜欢
      • 2011-12-15
      • 2016-01-17
      • 2014-01-26
      • 1970-01-01
      • 1970-01-01
      • 2023-02-10
      • 2011-01-25
      相关资源
      最近更新 更多