簡體   English   中英

為給定的鍵函數產生所有可能的等效排序

[英]Produce all possible equivalent sorts for a given key function

說我有幾點:

points = [(1., 1.), (3., 0.), (-1., -1.), (9., 2.), (-4., 2.) ]

如果按y軸對它們進行排序:

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

我懂了

 points = [(-1., -1.),  (3., 0.), (1.,1.) , (-4.,2.), (9., 2.)]

但是我想對它進行完全獨立於x軸的排序。 此外,我希望輸出是2個列表,它們顯示兩種可能的排序(即y值相等的x值的所有排列 ):

[(-1., -1.),  (3., 0.), (1.,1.) , (-4.,2.),(9., 2.)]
[(-1., -1.),  (3., 0.), (1.,1.) , (9.,2.), (-4.,2.)]

有辦法嗎?

問題陳述:

給定一個等價關系(例如比較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)))

最后結果:

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

說明:

  • 初始排序僅按y軸對點進行排序。 這使用itemgetter()提取字段1。

  • groupby()步驟將組成具有相同y坐標的點。

  • permutations()步驟生成每個組的所有可能的排序。

  • product()步驟生成每個排列組的笛卡爾乘積(以便每個輸出具有來自每個排列組的一個元素)。

  • chain.from_iterable()步驟將產品中的連續元組鏈接到一個可迭代的對象中,該可迭代對象可被饋送到list()中以產生所需的結果。

一步步:

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)創建具有相同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)生成具有相同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)使用每個排列組中的一個元素創建所有可能的序列:

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

僅對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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM