2016-02-28 51 views
5

词典列表的列表我有一个对象,它是字典的名单列表:排序在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" }]] 

如果它只是一个类型的字典的名单,然后:

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

会工作。我无法弄清楚如何做到这一点,没有循环在列表中,计算总和,然后排序。这就是我现在正在做的,但我试图通过删除循环来提高此代码的效率,因为我的列表中有100多个列表。

+2

正如一个注释:在这种情况下,你不需要尾随的'''''续行。由于行以逗号结尾,列表文字仍然“打开”,Python会自动期待下一行继续。 – poke

回答

4

你的想法已经是很不错的,使用自定义按键功能分类和使用summap并在play关键的itemgetter时:

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

你有一个问题存在,但:该key参数希望有一个函数能够处理你正在排序的列表项。但summap都不会返回一个函数,因此您不能将其用作关键函数。相反,你可以做一个lambda函数来为每个项目执行这个组合。

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

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

这是btw。在功能上等同于以下发电机的理解,这可能是更具可读性:

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

sorted使用这个应该工作,但你应该考虑直接排序列表使用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的默认排序确实保证:

与列表中的每个项目对应的键计算一次,然后用于整个排序过程。

所以,你将有一个非常有效的解决这个排序问题。

+0

它应该不是'reverse = True'以获得最高的第一个 –

+0

@PaulRooney哦,是的,我错过了这个问题的细节(尽管它与排序问题并不相关)。谢谢! – poke