Python for循环中的自定义排序

Python for循环中的自定义排序,python,c,arrays,algorithm,sorting,Python,C,Arrays,Algorithm,Sorting,假设给我一个n点坐标的数组。我想生成一个点的二维数组,其中第I行的所有元素都按照它们与第I个点的距离排序。可能会有更好、更有效的算法来获得最终结果,但出于某些原因,我想用朴素的算法来实现,即暴力。我也不想写我自己的排序函数 在C语言中,可以使用qsort函数,但是它的compare函数只接受两个参数,而我需要传递三个参数:参考点和另外两个要比较的点 在Python中,也可以使用排序函数,但同样,它的关键函数只接受一个参数,而在本例中,我需要传递两个参数 那么我该怎么做呢?可能使用嵌套的for循环

假设给我一个n点坐标的数组。我想生成一个点的二维数组,其中第I行的所有元素都按照它们与第I个点的距离排序。可能会有更好、更有效的算法来获得最终结果,但出于某些原因,我想用朴素的算法来实现,即暴力。我也不想写我自己的排序函数

在C语言中,可以使用qsort函数,但是它的compare函数只接受两个参数,而我需要传递三个参数:参考点和另外两个要比较的点

在Python中,也可以使用排序函数,但同样,它的关键函数只接受一个参数,而在本例中,我需要传递两个参数


那么我该怎么做呢?

可能使用嵌套的for循环,外部的for循环看着第I个点。然后在循环内计算所有距离。计算完成后,对该行使用本机python排序,然后将其添加到主2d数组中。

您可以定义一个函数,该函数获取相关信息引用、两点并将其映射到一个距离:

def deteremineDistance(reference, pt1, pt2):
    #determine distances according to your definition and store it in variable "dist"
    return dist

然后可以对该函数的结果进行排序,同时跟踪它们与实际数据的对应关系。

您可以定义函数生成函数,为每个点创建自定义距离函数

pts = [(1,1), (3,4), (1,8), (7,6)]

def mk_distsq(a):
    def distsq(b):
        return ((b[0]-a[0])**2 + (b[1]-a[1])**2)**0.5
    return distsq

dist = [sorted(pts, key=mk_distsq(pt)) for pt in pts]
lambda可以是闭包。但是,这很容易出错,因为当y的值在下一次迭代中更改时,所有lambda都开始使用新值。我相信这不会影响这段代码,但使用functools.partial会让我感觉更安全:


关于该职位的C部分: 使用全局变量。应该可以,但不是多线程安全的

假设OP具有比较功能,以比较与参考点之间的2个点距离:

int compare(const pt *a, const pt2 *b, const pt2 *ref);


让我们假设坐标列表绑定到对。那么这里有一个1-statement方式:

[sorted(pairs,
        key=lambda point: (point[0] - ref[0])**2 + (point[1] - ref[1])**2)
 for ref in pairs]
例如,假设:

pairs = [(1, 2), (2, 3), (3, 4), (4, 5)]
这将产生:

[[(1, 2), (2, 3), (3, 4), (4, 5)],
 [(2, 3), (1, 2), (3, 4), (4, 5)],
 [(3, 4), (2, 3), (4, 5), (1, 2)],
 [(4, 5), (3, 4), (2, 3), (1, 2)]]

请注意,除非需要实际距离,否则不需要提取平方根。为了进行排序,您可以通过查看距离的平方来获得相同的顺序。

设置中的行是什么?脏解决方案:将参考点作为全局变量传递。在2D数组中,第i行包含所有n个点,根据它们与点a_i的距离排序,其中a_i是n个点的输入1D数组中的第i个点。@chux:是的,这应该有效。或者,只需编写一个常规距离函数或平方距离,它给出了相同的排序顺序,并使用functools.partial来修复其中一个参数。y的值更改不会使lambda容易出错-事实上,使用partial的示例在每次迭代中依赖于相同的行为x更改,并且所有的partial都开始使用新值。@lvc:Nope!旧的局部对象如果仍然存在,则仍将使用其原始x值。参数在创建分部对象时绑定。
[sorted(pairs,
        key=lambda point: (point[0] - ref[0])**2 + (point[1] - ref[1])**2)
 for ref in pairs]
pairs = [(1, 2), (2, 3), (3, 4), (4, 5)]
[[(1, 2), (2, 3), (3, 4), (4, 5)],
 [(2, 3), (1, 2), (3, 4), (4, 5)],
 [(3, 4), (2, 3), (4, 5), (1, 2)],
 [(4, 5), (3, 4), (2, 3), (1, 2)]]