繁体   English   中英

在python中对字典列表进行排序

[英]Sorting a list of lists of dictionaries in python

我有一个对象是字典列表的列表:

myObject =[[{ "play": 5.00, "id": 1, "uid": "abc" },  \
            { "play": 1.00, "id": 2, "uid": "def" }], \
           [{ "play": 6.00, "id": 3, "uid": "ghi" },  \
            { "play": 7.00, "id": 4, "uid": "jkl" }], \
           [{ "play": 3.00, "id": 5, "uid": "mno" },  \
            { "play": 1.00, "id": 6, "uid": "pqr" }]]

我想按每个嵌套列表的字典中的play值之和对列表进行排序。 然后对象将按如下方式排序:

myObject =[[{ "play": 6.00, "id": 3, "uid": "ghi" },  \
            { "play": 7.00, "id": 4, "uid": "jkl" }], \
           [{ "play": 5.00, "id": 1, "uid": "abc" },  \
            { "play": 1.00, "id": 2, "uid": "def" }], \
           [{ "play": 3.00, "id": 5, "uid": "mno" },  \
            { "play": 1.00, "id": 6, "uid": "pqr" }]]

如果它只是一个dicts列表,那么:

sorted(myObject, key=sum(map(itemgetter(play))), reverse=True)

会工作。 如果不循环遍历列表,计算总和,然后排序,我无法弄清楚如何做到这一点。 这就是我现在正在做的事情,但我正在尝试通过删除循环来提高此代码的效率,因为我的列表中有数百万个列表。

你的想法已经非常好了,在排序时使用自定义键功能,并在play键上使用summapitemgetter

key=sum(map(itemgetter(play)))

你确实遇到了一个问题: key参数需要一个函数来获取你正在排序的列表项。 但是summap都没有返回函数,因此你不能将它用作关键函数。 相反,您可以创建一个lambda函数,为每个项目执行此组合。

其他问题是play应该是一个字符串'play' ,而该map应该将子列表作为参数。 所以你的关键功能看起来像这样:

key=lambda x: sum(map(itemgetter('play'), x))

这是顺便说一句。 在功能上等同于以下生成器理解,它可能更具可读性:

key=lambda x: sum(y['play'] for y in x)

使用sort和sorted应该可以工作但你应该考虑直接使用list.sort对列表进行list.sort

>>> myObject = [[{ "play": 5.00, "id": 1, "uid": "abc" },
                 { "play": 1.00, "id": 2, "uid": "def" }],
                [{ "play": 6.00, "id": 3, "uid": "ghi" },
                 { "play": 7.00, "id": 4, "uid": "jkl" }],
                [{ "play": 3.00, "id": 5, "uid": "mno" },
                 { "play": 1.00, "id": 6, "uid": "pqr" }]]

>>> myObject.sort(key=lambda x: sum(y['play'] for y in x), reverse=True)

>>> for x in myObject:
        print(x)

[{'play': 6.0, 'uid': 'ghi', 'id': 3}, {'play': 7.0, 'uid': 'jkl', 'id': 4}]
[{'play': 5.0, 'uid': 'abc', 'id': 1}, {'play': 1.0, 'uid': 'def', 'id': 2}]
[{'play': 3.0, 'uid': 'mno', 'id': 5}, {'play': 1.0, 'uid': 'pqr', 'id': 6}]

(顺便说一下, myObject对于一系列事物来说是一个坏名字。)


就问题的效率或复杂性而言,您实际上无法避免最终遍历每个子列表。 如果不查看这些值,就无法确定这些值的总和,所以很明显你无法避免这种情况。

但是,您应确保每次总和只计算一次,以避免不止一次查看子列表中的项目。 幸运的是,使用list.sort的默认排序确实可以保证:

对应于列表中每个项目的密钥计算一次,然后用于整个分类过程。

因此,您将为此排序问题提供非常有效的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM