【问题标题】:python multimdimensional sorting, combined valuespython多维排序,组合值
【发布时间】:2012-12-11 16:23:40
【问题描述】:

我有一个多维列表,我想对两个数字元素的组合权重进行排序,例如,结果使用:sorted(results, key=operator.itemgetter(2,3))

[..,1,34]
...
...
[..,10,2]
[..,11,1]
[..,13,3]
[..,13,3]
[..,13,3]
[..,16,1]
[..,29,1]

itemgetter 的问题是先按元素 2 排序,然后按元素 3,其中 我想将 13,3 放在顶部/底部(取决于 asc/desc 排序)。

这可能吗?如果可以,怎么做。

非常感谢

编辑 1。

对不起,我正在处理 dom 数据,来自搜索页面的结果,可以这么说,它是一个通用的搜索引擎搜索器。

我正在做的是找到 a 和 div 标签,然后我创建一个特定类或 id 出现在 div/a 标签上的项目的计数,这是元素 2,然后我再次重新扫描找到的标签列表并查看标签的其他类/id 与正在处理的当前标签的总数相匹配,因此在这种情况下,项目 13,3 与该类型标签的类/id 匹配 13 个,3 表示还有 3 个其他标签具有相同次数的类/ID,因此为什么我希望这样排序,不,它不是字典,它绝对是一个列表。

谢谢。

【问题讨论】:

  • 你没有有一个多维列表/字典。你有一个具有元组键的字典。这是非常不同的,因为它意味着例如(0,1) 和 (0,2) 键的共同点与 foo 和 bar 一样多。
  • 为什么13,3应该在顶部或底部? 13 和 3 都不是最小值或最大值。
  • 你能把你的问题说得更清楚吗?您想使用的排序算法到底是什么?例如,为什么 (13,3) 会在顶部?
  • 为什么你认为[..,13,3]应该在顶部/底部?
  • “组合加权”是什么意思?

标签: python list sorting multidimensional-array


【解决方案1】:

是的,您可以编写任何您想要的函数作为键函数。例如,如果您想按第二个和第三个元素的总和进行排序:

def keyfunc(item):
    return sum(operator.itemgetter(2, 3)(item))

sorted(results, key=keyfunc)

因此,如果您将此函数用作 keyfunc,则将 13 作为第二个元素 3 作为列表的第三个元素的项目将被排序,就好像它是值 16。

不清楚您想如何对这些元素进行排序,但您可以更改 keyfunc 的主体以执行您想要的任何操作。

【讨论】:

  • 如果“组合加权”涉及多个项目,keyfunc() 可能还不够,请参阅collections.Counter 中的示例`@jdotjdot's answer
【解决方案2】:

鉴于没有任何其他解释,我在这里进行了全面猜测,并假设您实际上想要做的是按列表中最后两个键的 product 排序,其次按产品中第一个元素的大小排序。对于为什么(13,3) 会是最佳结果,这是我能想出的唯一解释。

在这种情况下,你会寻找这样的东西:

sorted(results, key=lambda x: (x[-2]*x[-1], x[-2]), reverse=True)

这会给你以下排序:

[[13, 3], [13, 3], [13, 3], [1, 34], [29, 1], [10, 2], [16, 1], [11, 1]]

或者,如果您在此处实际查找的结果是按结果在列表中出现的次数排序,我们可以使用collections.Counter。不幸的是,列表不是可散列的,所以我们会作弊并将它们转换为元组以用作键。有很多方法可以解决这个问题,但这是我目前展示我在说什么的最简单的方法。

import collections, json
def sort_results(results):
    c = collections.Counter([tuple(k) for k in results])
    return sorted(c, key=lambda x: c[x], reverse=True)

这会让你:

[(13, 3), (1, 34), (16, 1), (29, 1), (11, 1), (10, 2)]

谢谢J.F. Sebastian 指出可以使用元组代替str!

【讨论】:

  • 感谢您的回答,这正是我一直在寻找的,我对 Python 非常熟悉,但我仍在学习大量可用的功能。代码几乎完成了,只需进行一些整理和测试,我将拥有一个通用的搜索引擎搜索器,顺便说一句,我不是在重新发明轮子,只是找不到一个能完全满足我需要的实用程序
  • 您可以使用tuple 而不是str 来避免最后的json.loads:Counter(map(tuple, results)) 假设是二维列表。 key=c.get 也可以代替 lambda 工作。
  • @J.F.谢谢,没有意识到元组是可散列的。会更新。我正在考虑使用 c.get 之类的东西,但我只是认为 lambda 可以更清楚地说明发生了什么,老实说。
猜你喜欢
  • 2019-10-16
  • 2023-04-02
  • 1970-01-01
  • 2017-01-26
  • 2017-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多