【问题标题】:Python: sorting a zip based on length and weightPython:根据长度和重量对 zip 进行排序
【发布时间】:2016-07-07 07:53:34
【问题描述】:

在 Python 2 中,假设我们有两个列表:

list1 = [["A"],["A","B"],["B","D"],["C"],["A","B","D"]]
list2 = [5,10,10,15,10]

我想根据 list2(权重)对 list1 进行降序排序,只要两个项目的权重相同(例如 x = ["A","B","D"] 和 y = [" B","D"] 的权重为 10),长度大的在前。对于 list1 和 list 2,我希望输出如下:

[["C"], ["A","B","D"], ["A","B"],["B","D"],["A"]]

这怎么可能?

我所知道的是,我们可以通过首先定义仅根据大小对它们进行排序

zipped = zip(list1,list2)

然后:

zipped.sort(key=lambda t: t[1],reverse=True)

【问题讨论】:

  • 我认为您的意思是您要根据 list2 而不是您编写的方式对 list1 进行排序。
  • @BurhanKhalid 你是对的。已编辑。
  • 良好的第一步。现在你有什么尝试?
  • 我假设您使用的是 Python 2,因为zip 在 Python 3 中返回一个迭代器。
  • @JulienBernu 第二步,我想提取具有相同重量的项目。然后,定义一个等于每个项目长度的新权重,并根据新权重对它们进行排序。

标签: python sorting


【解决方案1】:

为了按多个参数排序,key 函数应该返回一个元组:

In [6]: sorted(zip(list1, list2), key=lambda x: (x[1], len(x[0])), reverse=True)
Out[6]: 
[(['C'], 15),
 (['A', 'B', 'D'], 10),
 (['A', 'B'], 10),
 (['B', 'D'], 10),
 (['A'], 5)]

key=lambda x: (x[1], len(x[0])) 应该读作“首先按 x[1] 中的权重排序,然后按 x[0] 中列表的长度排序”

为了从每个元组中检索第一个元素,您可以将结果包装到列表推导中:

In [7]: [x[0] for x in sorted(zip(list1, list2), key=lambda x: (x[1], len(x[0])), reverse=True)]
Out[7]: [['C'], ['A', 'B', 'D'], ['A', 'B'], ['B', 'D'], ['A']]

【讨论】:

  • @PM2Ring,当然,但这也是 Python 禅宗的一部分:“应该有一种——最好只有一种——明显的方法。” :)
  • @soon 谢谢,我不知道我们可以在“key”中给出多个条件。
  • @m0_as,实际上,根本没有魔法 - 只是尝试比较 REPL 中的一些元组,例如:(1, 2) > (1, 3)(1, 2) > (1, 1)(2, 2) > (1, 10)
  • @很快我明白了。良好的观察力。
【解决方案2】:

list2 权重相同时,您的关键函数需要告诉sort 检查list1 项目的长度。您可以通过将键设为元组来做到这一点,如下所示:

list1 = [["A"],["A","B"],["B","D"],["C"],["A","B","D"]]
list2 = [5,10,10,15,10]

zipped = zip(list1,list2)

zipped.sort(key=lambda t: (t[1], len(t[0])), reverse=True)

print(list(zip(*zipped)[0]))

输出

[['C'], ['A', 'B', 'D'], ['A', 'B'], ['B', 'D'], ['A']]

FWIW,这是一个适用于 Python 3 和 Python 2 的版本。我之前的代码不适用于 Python 3,因为 Python 3 zip 返回的是迭代器,而不是列表。

zipped = zip(list1, list2)
zipped = sorted(zipped, key=lambda t: (t[1], len(t[0])), reverse=True)
newlist = [t[0] for t in zipped]
print(newlist)

【讨论】:

  • @soon 感谢您的完整回复。
猜你喜欢
  • 1970-01-01
  • 2017-04-02
  • 1970-01-01
  • 2011-02-04
  • 2018-03-29
  • 1970-01-01
  • 2018-02-23
  • 2013-11-05
相关资源
最近更新 更多