Python 为给定的键函数生成所有可能的等价排序

Python 为给定的键函数生成所有可能的等价排序,python,sorting,grouping,permutation,equivalence-classes,Python,Sorting,Grouping,Permutation,Equivalence Classes,说我有几点: points = [(1., 1.), (3., 0.), (-1., -1.), (9., 2.), (-4., 2.) ] 如果我按y轴对它们进行排序: points = sorted(points , key=lambda k: [k[1], k[0]]) 我明白了 但是我想对它进行排序,完全独立于x轴此外,我希望输出是两个列表,显示两种可能的排序(即y值相等的x值的所有排列): 有什么方法可以做到这一点吗?仅按x值排序: points = sorted(poi

说我有几点:

points = [(1., 1.), (3., 0.), (-1., -1.), (9., 2.), (-4., 2.) ]
如果我按y轴对它们进行排序:

 points = sorted(points , key=lambda k: [k[1], k[0]])
我明白了

但是我想对它进行排序,完全独立于x轴此外,我希望输出是两个列表,显示两种可能的排序(即y值相等的x值的所有排列)


有什么方法可以做到这一点吗?

仅按x值排序:

    points = sorted(points , key=lambda k: k[1])
    points

    [(-1.0, -1.0), (3.0, 0.0), (1.0, 1.0), (9.0, 2.0), (-4.0, 2.0)]
问题陈述: 创建多个列表,列出给定等价关系的所有可能的排序排列(例如比较y坐标并忽略x坐标):

解决方案: 下面是一些解决此问题的工作代码:

from operator import itemgetter
from itertools import groupby, product, permutations, chain

points = [(1., 1.),  (3., 0.),(-1., -1.) , (9., 2.), (-4., 2.) ]
points.sort(key=itemgetter(1))
groups = [list(permutations(g)) for k, g in groupby(points, itemgetter(1))]
for t in product(*groups):
    print(list(chain.from_iterable(t)))
最终结果: 说明:
  • 初始排序仅按y轴对点进行排序。这用于提取字段1

  • 该步骤生成具有相同y坐标的点组

  • 该步骤生成每个组的所有可能订单

  • 该步骤生成每个置换组的笛卡尔积(以便每个输出具有来自每个置换组的一个元素)

  • 该步骤将产品中的连续元组链接到一个iterable中,该iterable可输入到该iterable中以生成所需的结果

逐步: 1) 按y坐标对点进行排序,忽略x坐标:

>>> points = [(1., 1.),  (3., 0.),(-1., -1.) , (9., 2.), (-4., 2.)]
>>> points.sort(key=itemgetter(1))
>>> points
[(-1.0, -1.0), (3.0, 0.0), (1.0, 1.0), (9.0, 2.0), (-4.0, 2.0)]
>>>       ^-----------^-----------^-----------^-------------^ ascending y-values
>>> pprint([list(g) for k, g in groupby(points, itemgetter(1))], width=40)
[[(-1.0, -1.0)],                                            # y = -1.0  
 [(3.0, 0.0)],                                              # y =  0.0
 [(1.0, 1.0)],                                              # y =  1.0 
 [(9.0, 2.0), (-4.0, 2.0)]]                                 # y =  2.0 
>>> groups = [list(permutations(g)) for k, g in groupby(points, itemgetter(1))]
>>> pprint(groups)
[[((-1.0, -1.0),)],                                         # y = -1.0
 [((3.0, 0.0),)],                                           # y =  0.0 
 [((1.0, 1.0),)],                                           # y =  1.0 
 [((9.0, 2.0), (-4.0, 2.0)), ((-4.0, 2.0), (9.0, 2.0))]]    # y =  2.0
2) 创建具有相同y坐标的点组:

>>> points = [(1., 1.),  (3., 0.),(-1., -1.) , (9., 2.), (-4., 2.)]
>>> points.sort(key=itemgetter(1))
>>> points
[(-1.0, -1.0), (3.0, 0.0), (1.0, 1.0), (9.0, 2.0), (-4.0, 2.0)]
>>>       ^-----------^-----------^-----------^-------------^ ascending y-values
>>> pprint([list(g) for k, g in groupby(points, itemgetter(1))], width=40)
[[(-1.0, -1.0)],                                            # y = -1.0  
 [(3.0, 0.0)],                                              # y =  0.0
 [(1.0, 1.0)],                                              # y =  1.0 
 [(9.0, 2.0), (-4.0, 2.0)]]                                 # y =  2.0 
>>> groups = [list(permutations(g)) for k, g in groupby(points, itemgetter(1))]
>>> pprint(groups)
[[((-1.0, -1.0),)],                                         # y = -1.0
 [((3.0, 0.0),)],                                           # y =  0.0 
 [((1.0, 1.0),)],                                           # y =  1.0 
 [((9.0, 2.0), (-4.0, 2.0)), ((-4.0, 2.0), (9.0, 2.0))]]    # y =  2.0
3) 生成具有相同y坐标的点的所有排列:

>>> points = [(1., 1.),  (3., 0.),(-1., -1.) , (9., 2.), (-4., 2.)]
>>> points.sort(key=itemgetter(1))
>>> points
[(-1.0, -1.0), (3.0, 0.0), (1.0, 1.0), (9.0, 2.0), (-4.0, 2.0)]
>>>       ^-----------^-----------^-----------^-------------^ ascending y-values
>>> pprint([list(g) for k, g in groupby(points, itemgetter(1))], width=40)
[[(-1.0, -1.0)],                                            # y = -1.0  
 [(3.0, 0.0)],                                              # y =  0.0
 [(1.0, 1.0)],                                              # y =  1.0 
 [(9.0, 2.0), (-4.0, 2.0)]]                                 # y =  2.0 
>>> groups = [list(permutations(g)) for k, g in groupby(points, itemgetter(1))]
>>> pprint(groups)
[[((-1.0, -1.0),)],                                         # y = -1.0
 [((3.0, 0.0),)],                                           # y =  0.0 
 [((1.0, 1.0),)],                                           # y =  1.0 
 [((9.0, 2.0), (-4.0, 2.0)), ((-4.0, 2.0), (9.0, 2.0))]]    # y =  2.0
4) 使用每个置换组中的一个元素创建所有可能的序列:

>>> for t in product(*groups):
        print(t)

(((-1.0, -1.0),), ((3.0, 0.0),), ((1.0, 1.0),), ((9.0, 2.0), (-4.0, 2.0)))
(((-1.0, -1.0),), ((3.0, 0.0),), ((1.0, 1.0),), ((-4.0, 2.0), (9.0, 2.0)))
5) 将每个子序列合并为一个列表:

>>> for t in product(*groups):
        list(chain.from_iterable(t))

[(-1.0, -1.0), (3.0, 0.0), (1.0, 1.0), (9.0, 2.0), (-4.0, 2.0)]
[(-1.0, -1.0), (3.0, 0.0), (1.0, 1.0), (-4.0, 2.0), (9.0, 2.0)]

这会给我你刚刚证明和排序过的列表(list,key=lambda k:[k[1],k[0]])会给我我提到的那个,但是想象一下,(2,2)这些解决方案也不会起作用。还不完全清楚你想要第二个解决方案的顺序是什么;你能澄清一下吗?我想要的是给我关于x值的y的所有可能的排序顺序,所以如果只有2个数字重复,你所写的和我所拥有的将解决这个问题,但是如果我们有一个y轴2的第三个数字,这个问题将无法解决。请不要使用内置变量的名称;将
列表
替换为
;这将为你(和其他人)省去很多悲伤!