【问题标题】:Sort a list of candidates according to a metric - Python?根据指标对候选人列表进行排序 - Python?
【发布时间】:2013-10-05 13:37:19
【问题描述】:

我有一个二维点列表

candidates = [(x1, y1), (x2, y2), (x3, y3), ...]

和一个参考点ref = (x0, y0)

我现在希望根据它们与参考点ref 的欧几里得距离,按升序对列表candidates 进行排序。

最 Pythonic 的方式是什么?

【问题讨论】:

    标签: python list sorting


    【解决方案1】:

    (x1, y1)(x2, y2) 两点之间的欧几里得距离由下式给出:

    sqrt((x1 - y1)^2 + (x2 - y2)^2))
    

    要对列表进行排序,您可以使用公式,也可以跳过sqrt 部分,因为您只是进行比较,而不是计算实际距离。即:

    if x > y then sqrt(x) > sqrt(y)
    

    因此,以下将起作用:

    ref = (x0, y0)
    candidates = [(x1, y1), (x2, y2), (x3, y3), ...]
    
    candidates.sort(key=lambda x: (x[0] - ref[0]) ** 2 + (x[1] - ref[1]) ** 2)
    

    【讨论】:

      【解决方案2】:

      编写一个函数来计算欧几里得距离并将该函数与list.sort 函数的key 参数一起使用。

      ref = (x0, y0)
      def euclidean(coords):
          xx, yy = ref
          x, y = coords
          return ((x-xx)**2 + (y-yy)**2)**0.5
      
      candidates = [(x1, y1), (x2, y2), (x3, y3), ...]
      candidates.sort(key=euclidean)
      

      【讨论】:

      • 我会使用math.sqrt(x) 而不是x**.5,它大约快30%。同样,x*x - 2*x*xx + xx*xx(x-xx)**2 快。
      • @TimPietzcker 我同意math.sqrt(x) 更具可读性,但函数调用总是比**.5 慢。
      • 不。 timeit.timeit(setup="from math import sqrt", stmt="[sqrt(x) for x in range(100,200)]") 在我的机器上的结果是 23 秒,而 timeit.timeit(stmt="[x**.5 for x in range(100,200)]") 需要 32 秒。
      • 好吧,我会避免使用sqrt** 0.5。这里不需要。
      • @perfectm1ng:在 Python 控制台输入 import this,您会看到。更笼统地说,人类可读性在任何时候都胜过聪明。编译器并不关心你编写脚本的冗长程度。
      【解决方案3】:

      list.sort()key 参数将允许您传递一个函数,该函数将用于派生每个元素的排序键。

      candidates.sort(key=lambda x: distance(ref, x))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-27
        • 2019-12-23
        • 2018-10-22
        相关资源
        最近更新 更多