2016-02-28 55 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