[英]Produce all possible equivalent sorts for a given key function
Say I have points: 说我有几点:
points = [(1., 1.), (3., 0.), (-1., -1.), (9., 2.), (-4., 2.) ]
If I sort them by y axis: 如果按y轴对它们进行排序:
points = sorted(points , key=lambda k: [k[1], k[0]])
I get 我懂了
points = [(-1., -1.), (3., 0.), (1.,1.) , (-4.,2.), (9., 2.)]
However I want to sort it completely independent from the x axis. 但是我想对它进行完全独立于x轴的排序。 Further, I want the output to be the 2 lists which show both possible sorts (ie all permutations of the x-values where the y-values are equal ):
此外,我希望输出是2个列表,它们显示两种可能的排序(即y值相等的x值的所有排列 ):
[(-1., -1.), (3., 0.), (1.,1.) , (-4.,2.),(9., 2.)]
[(-1., -1.), (3., 0.), (1.,1.) , (9.,2.), (-4.,2.)]
Is there a way I can do this? 有办法吗?
Create multiple lists of all possible permutations of sorts given an equivalence relation (such as comparing y-coodinates and ignoring the x-coordinates): 给定一个等价关系(例如比较y坐标并忽略x坐标),创建所有可能的排列排列的多个列表:
Here is some working code to solve the problem: 以下是一些解决该问题的有效代码:
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)))
[(-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)]
The initial sort orders the points by the y-axis only. 初始排序仅按y轴对点进行排序。 This uses itemgetter() to extract field 1.
这使用itemgetter()提取字段1。
The groupby() step makes groups of points that have the same y-coordinate. groupby()步骤将组成具有相同y坐标的点。
The permutations() step generates all possible orderings of each group. permutations()步骤生成每个组的所有可能的排序。
The product() step generates the cartesian product of each of the permutation groups (so that each output has one element from each of the permutation groups). product()步骤生成每个排列组的笛卡尔乘积(以便每个输出具有来自每个排列组的一个元素)。
The chain.from_iterable() step links consecutive tuples in the product into a single iterable which can be fed into list() to make the desired result. chain.from_iterable()步骤将产品中的连续元组链接到一个可迭代的对象中,该可迭代对象可被馈送到list()中以产生所需的结果。
1) Sort the points by the y-coordinate, ignoring the x-coordinate: 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
2) Create groups of points that have the same y-coordinate: 2)创建具有相同y坐标的点组:
>>> 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
3) Generate all permutations of points that have the same y-coordinate: 3)生成具有相同y坐标的点的所有排列:
>>> 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) Create all possible sequences with one element from each permutation group: 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) Combine each subsequence into a single list: 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)]
To sort on the x values only: 仅对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)]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.