【问题标题】:Sort Python list using multiple keys使用多个键对 Python 列表进行排序
【发布时间】:2017-09-09 22:12:26
【问题描述】:

我已经为此搜索了很多时间。我对使用关键参数进行排序有了一些想法。

我有一个这样的元组列表。通过 OpenCV 霍​​夫圆检测得到。

correctC = [(298, 172, 25), (210, 172, 25), (470, 172, 25), (386, 172, 22), (648, 172, 25), (384, 44, 22), (558, 110, 22), (562, 170, 25), (382, 108, 25), (734, 172, 25), (126, 172, 24), (646, 44, 22), (296, 110, 23), (126, 234, 26), (470, 236, 25), (296, 44, 25), (208, 108, 24), (38, 170, 25), (730, 110, 22), (730, 44, 25), (468, 110, 23), (468, 44, 25), (208, 44, 25), (124, 44, 22), (558, 44, 22), (36, 110, 24), (36, 44, 22), (298, 234, 26), (210, 236, 25), (648, 234, 25), (732, 234, 22), (562, 234, 26), (384, 236, 25), (38, 234, 26), (646, 110, 25), (124, 112, 27)]

它有 3 个值。中心坐标(x,y)和半径。

我需要使用它的 x 和 y 值对所有元组进行排序。

我可以单独进行这种排序。

xS=sorted(correctC,key=lambda correctC: correctC[0])

这是根据 x 值排序。

yS=sorted(correctC,key=lambda correctC: correctC[1])

这是根据 y 值排序的。

我怎样才能同时使用一个表达式(根据 x 值和 y 值)?

我使用的是 Python 2.7

【问题讨论】:

  • x和y的小于、等于和大于的定义是什么?具体来说,哪个更小,(1, 2, 3) 或 (2, 1, 3),或者它们被认为是相等的排序?还是应该将 x 和 y 转换为极坐标并使用长度进行排序?
  • correctC 是 lambda 参数的错误名称,因为您对列表及其元素重复使用相同的变量名称。
  • 您应该将预期的输出添加到您的问题中。
  • 这能回答你的问题吗? Sort a list by multiple attributes?

标签: python python-2.7 list sorting


【解决方案1】:

对于任何对组合感到困惑的人

  • 不清楚的问题
  • 接受的答案
  • OP user119o的cmets

看起来 OP 想要这样的东西:

sortedC = sorted(correctC)
for index in range(0, len(sortedC), 4):
    sortedC[index:index + 4] = sorted(sortedC[index:index + 4], key=lambda x: x[1])

元组的第二列显示了预期的输出(应该包含在问题中):

 0  ( 36,  44,  22)  ( 36,  44,  22)  
 1  ( 36, 110,  24)  ( 36, 110,  24)  
 2  ( 38, 170,  25)  ( 38, 170,  25)  
 3  ( 38, 234,  26)  ( 38, 234,  26)  
 4  (124,  44,  22)  (124,  44,  22)  
 5  (124, 112,  27)  (124, 112,  27)  
 6  (126, 172,  24)  (126, 172,  24)  
 7  (126, 234,  26)  (126, 234,  26)  
 8  (208,  44,  25)  (208,  44,  25)  
 9  (208, 108,  24)  (208, 108,  24)  
10  (210, 172,  25)  (210, 172,  25)  
11  (210, 236,  25)  (210, 236,  25)  
12  (296,  44,  25)  (296,  44,  25)  
13  (296, 110,  23)  (296, 110,  23)  
14  (298, 172,  25)  (298, 172,  25)  
15  (298, 234,  26)  (298, 234,  26)  
16  (382, 108,  25)  (384,  44,  22)  True
17  (384,  44,  22)  (382, 108,  25)  True
18  (384, 236,  25)  (386, 172,  22)  True
19  (386, 172,  22)  (384, 236,  25)  True
20  (468,  44,  25)  (468,  44,  25)  
21  (468, 110,  23)  (468, 110,  23)  
22  (470, 172,  25)  (470, 172,  25)  
23  (470, 236,  25)  (470, 236,  25)  
24  (558,  44,  22)  (558,  44,  22)  
25  (558, 110,  22)  (558, 110,  22)  
26  (562, 170,  25)  (562, 170,  25)  
27  (562, 234,  26)  (562, 234,  26)  
28  (646,  44,  22)  (646,  44,  22)  
29  (646, 110,  25)  (646, 110,  25)  
30  (648, 172,  25)  (648, 172,  25)  
31  (648, 234,  25)  (648, 234,  25)  
32  (730,  44,  25)  (730,  44,  25)  
33  (730, 110,  22)  (730, 110,  22)  
34  (732, 234,  22)  (734, 172,  25)  True
35  (734, 172,  25)  (732, 234,  22)  True

如果第四列中有True,则预期输出不同于sorted(correctC)

【讨论】:

    【解决方案2】:

    假设您想按与原点的距离排序,这就是您想要的:

    import math
    
    sortedC = sorted(correctC, 
                     cmp=lambda lhs, rhs: cmp(math.sqrt(lhs[0] ** 2 + lhs[1] ** 2),
                                              math.sqrt(rhs[0] ** 2 + rhs[1] ** 2)))
    

    【讨论】:

    【解决方案3】:

    在这种特殊情况下,如果您不关心具有相等 x, y 值的点如何排列,只需调用 sort 即可。元组按字典顺序排序。

    correctC.sort()
    

    如果您想更明确,请按照其他答案的说明进行操作:

    correctC.sort(key=lambda t: (t[0], t[1]))
    

    【讨论】:

      【解决方案4】:

      为什么您需要提供密钥?默认情况下,元组按字典顺序(“字典顺序”)排序。将比较第一个元素。如果它们相同,则将比较每个元组的第二个元素,依此类推。这意味着比较第一个元素,如果它们相同,则转到下一个元素(基本上是“字典排序”)。如果你依靠这个,你会得到你想要的,除了如果两个圆有相同的中心,那么它们也会按半径排序。

      【讨论】:

        【解决方案5】:

        据我所知,这有帮助:

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

        排序结果:

        [(36, 44, 22), (36, 110, 24), (38, 170, 25), (38, 234, 26), (124, 44, 22), (124, 112, 27), (126, 172, 24), (126, 234, 26), (208, 44, 25), (208, 108, 24), (210, 172, 25), (210, 236, 25), (296, 44, 25), (296, 110, 23), (298, 172, 25), (298, 234, 26), (382, 108, 25), (384, 44, 22), (384, 236, 25), (386, 172, 22), (468, 44, 25), (468, 110, 23), (470, 172, 25), (470, 236, 25), (558, 44, 22), (558, 110, 22), (562, 170, 25), (562, 234, 26), (646, 44, 22), (646, 110, 25), (648, 172, 25), (648, 234, 25), (730, 44, 25), (730, 110, 22), (732, 234, 22), (734, 172, 25)]
        

        【讨论】:

        • 编写 lambda 的更简洁方式,因为 OP 使用的是 Python 2:key= lambda (x, y, z): (x, y)。或lambda tup: tup[:2] 用于 Python 3。
        • @timgeb 这不是元组的默认排序顺序吗? (除了你忽略第三个元素。)
        • correctC 是 lambda 参数的错误名称,因为您为列表及其元素重用了相同的变量名称。 (不过,我看到该名称选择来自问题本身。)
        • @trust512 感谢您的回答....但是看,18 和 19 / 34 和 35 个元素......元素没有正确排序。 18 = (384, 236, 25) 19 = (386, 172, 22) 以上2个元组未正确按照y值和34和35排序 34 = (732, 234, 22) 35 = (734, 172, 25 ) 我也可以从我的最后一个结果中看到它,drive.google.com/file/d/0B53F0wBGnYhddktMV1ZTQlhGZHc/…
        • @user119o:“以上 2 个元组未根据 y 值正确排序” - 是的,因为它们是按 x 值排序的。图片中的圆圈没有排列成完美的列。如果您想检测近似的网格结构并按该结构对圆进行排序,则需要比按两个键排序更复杂的东西。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-24
        相关资源
        最近更新 更多