【问题标题】:How to sort a list of tuples based on the keys in a list?如何根据列表中的键对元组列表进行排序?
【发布时间】:2016-10-24 14:51:30
【问题描述】:

我想根据键的数量对元组列表进行排序。例如,我有这个元组列表:

list_t = [(1, 3, 5, 6, 9, 10), (1, 2, 3, 4, 5, 61), (1, 2, 3, 0, 9, 81), (1, 2, 6, 7, 9, 54), (1, 3, 5, 6, 12, 43)]

有一次我想按元组的第一个、第二个、第三个和第五个元素对其进行排序:

keys = [0, 1, 2, 4]
list_t_sorted = [(1, 2, 3, 4, 5, 61), (1, 2, 3, 0, 9, 81), (1, 2, 6, 7, 9, 54), (1, 3, 5, 6, 9, 10), (1, 3, 5, 6, 12, 43)]

还有一次我需要按元组的第三个元素对其进行排序:

keys = [2]
list_t_sorted = [(1, 2, 3, 4, 5, 61), (1, 2, 3, 0, 9, 81), (1, 3, 5, 6, 9, 10), (1, 3, 5, 6, 12, 43), (1, 2, 6, 7, 9, 54)]

到目前为止,我尝试了这段代码,但它没有返回预期的结果:

def sort_list(keys, list_t):
    return sorted(list_t, key=lambda l: (l[x] for x in keys))

例如,对于键 = [0, 1, 2, 4],它返回 [(1, 3, 5, 6, 9, 10), (1, 2, 3, 4, 5, 61), ( 1, 3, 5, 6, 12, 43), (1, 2, 6, 7, 9, 54), (1, 2, 3, 0, 9, 81)] 不按键排序。

有人可以帮助我吗?谢谢!

【问题讨论】:

  • 你说它没有返回预期的结果。它返回什么
  • 基于键的未排序的元组列表。例如,对于 keys = [0, 1, 2, 4],它返回 [(1, 3, 5, 6, 9, 10), (1, 2, 3, 4, 5, 61), (1, 3, 5, 6, 12, 43), (1, 2, 6, 7, 9, 54), (1, 2, 3, 0, 9, 81)],不按key排序!

标签: python list sorting tuples list-comprehension


【解决方案1】:

给你。你可以阅读更多关于operator.itemgetterhere in the docs的信息。

import operator
list_t = [(1, 3, 5, 6, 9, 10), (1, 2, 3, 4, 5, 61), (1, 2, 3, 0, 9, 81), (1, 2, 6, 7, 9, 54), (1, 3, 5, 6, 12, 43)]
keys = [0, 1, 2, 4]
sorted(list_t, key=operator.itemgetter(*keys))

输出:

[(1, 2, 3, 4, 5, 61),
 (1, 2, 3, 0, 9, 81),
 (1, 2, 6, 7, 9, 54),
 (1, 3, 5, 6, 9, 10),
 (1, 3, 5, 6, 12, 43)]

【讨论】:

  • 非常感谢您的快速回答!
【解决方案2】:

michael_j_ward 的回答是对您的问题的更简洁的解决方案,但如果您想知道您最初的想法出了什么问题:

您正在尝试对生成器对象进行排序,我猜它有不同的等同方式。显示这一点的一种方法是显示您实际尝试使用 for 循环排序的内容:

>>> def sort_list(keys, list_t):
...     for l in list_t:
...             print (l[x] for x in keys)
...     return sorted(list_t, key = lambda l: (l[x] for x in keys))
...
>>> sort_list(keys, list_t)
<generator object <genexpr> at 0x105bc1af0>
<generator object <genexpr> at 0x105bc1af0>
<generator object <genexpr> at 0x105bc1af0>
<generator object <genexpr> at 0x105bc1af0>
<generator object <genexpr> at 0x105bc1af0>
[(1, 3, 5, 6, 12, 43), (1, 2, 6, 7, 9, 54), (1, 2, 3, 0, 9, 81), (1, 2, 3, 4, 5, 61), (1, 3, 5, 6, 9, 10)]

这显然不是您想要的输出,它与这些生成器的比较方式有关。如果你想用你最初的想法来做(没有itemgetter),显式创建tuples而不是生成器:

>>> def sort_list(keys, list_t):
...     return sorted(list_t, key = lambda l: tuple(l[x] for x in keys))
...
>>> sort_list(keys, list_t)
[(1, 2, 3, 4, 5, 61), (1, 2, 3, 0, 9, 81), (1, 2, 6, 7, 9, 54), (1, 3, 5, 6, 9, 10), (1, 3, 5, 6, 12, 43)]

【讨论】:

  • 感谢您的详细说明!
猜你喜欢
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2022-01-24
  • 2021-04-20
  • 1970-01-01
  • 1970-01-01
  • 2015-11-23
相关资源
最近更新 更多