2011-12-22 95 views
0

我有一個最外層列表,其中包含此格式不同項目的每月總數。每個月都有相同的物品。基於Python中元組中第一個字段的總和對元組列表進行排序

big_list = [ 
    [ 
    (20, 'Item A', 'Jan'), 
    (30, 'Item B', 'Jan'), 
    (12, 'Item C', 'Jan'), 
    ], 
    [ 
    (22, 'Item A', 'Feb'), 
    (34, 'Item B', 'Feb'), 
    (15, 'Item C', 'Feb'), 
    ], 

    .... # until 'Dec' 
] 

而且我想根據一年中項目總數統計該列表。 (全年特定項目的元組中第一個字段的總和)。舉例來說,如果Item C在兩個月之後Item AItem B最計數,最終的結果將是

[ 
    [ 
    (12, 'Item C', 'Jan'), 
    (20, 'Item A', 'Jan'), 
    (30, 'Item B', 'Jan'), 
    ], 
    [ 
    (15, 'Item C', 'Feb'), 
    (22, 'Item A', 'Feb'), 
    (34, 'Item B', 'Feb'), 
    ], 

    ... # until 'Dec' 
] 
# Item C = 12 + 15 = 27 
# Item A = 20 + 22 = 42 
# Item B = 30 + 34 = 64 

我怎樣才能做到這一點?任何幫助或啓發將不勝感激。

+0

不要在子列表中的元素總是以相同的順序? – soulcheck 2011-12-22 14:32:54

+1

對於你的例子,你說'Item C'具有最多的計數(元組中第一個字段的總和?),後面跟着'Item A',但似乎並非如此。 「項目C」具有最少的計數,「項目B」具有最多的計數。 – MattH 2011-12-22 14:45:01

+0

哦,是的,我很抱歉。任何訂單(升序/降序)都可以,只要它們被分類。 – 2011-12-22 14:48:15

回答

3
big_list = [ 
    [ 
    (20, 'Item A', 'Jan'), 
    (30, 'Item B', 'Jan'), 
    (12, 'Item C', 'Jan'), 
    ], 
    [ 
    (22, 'Item A', 'Feb'), 
    (34, 'Item B', 'Feb'), 
    (15, 'Item C', 'Feb'), 
    ]] 

s = {} 
for l in big_list: 
    for m in l: 
     s[m[1]] = s.get(m[1], 0) + m[0] 

給我們s - 總和我們要使用排序:{'Item A': 42, 'Item B': 64, 'Item C': 27}

最後:

for l in big_list: 
    l.sort(key=lambda x: s[x[1]]) 

改變big_list到:

[[(12, 'Item C', 'Jan'), (20, 'Item A', 'Jan'), (30, 'Item B', 'Jan')], 
[(15, 'Item C', 'Feb'), (22, 'Item A', 'Feb'), (34, 'Item B', 'Feb')]] 

該解決方案適用於按任何順序在幾個月內列出並且如果som e項目不會在某個月出現。

0

@Pankrat接近:

for inner in big_list: 
    inner.sort() 

你有一個列表的列表裏面,這樣一個簡單的list.sort()將無法​​正常工作在這一點。你必須進入內層列表來排序它(它包含元組)。

幸運的是,你的情況只需要你排序元組中的第一個元素;如果你有別人排序,那麼你就需要別的東西,像這樣:

for inner in big_list: 
    inner.sort(key = lambda x: x[i]) # i is the index location you want to sort on 
0

我提出的解決方案:

[sublist.sort() for sublist in biglist] 

事後biglist排序。你不必分配列表理解!

+1

雖然它在這個例子中起作用,但它不是正確的答案。按年度總和排序。 – eumiro 2011-12-22 14:39:58

+0

這是這個例子的解決方案。它做OP沒有要求什麼,沒有什麼。這不是答案,你的例子肯定是更通用和更廣泛的範圍。 – 2011-12-22 14:52:35

1

如果你真的需要一個兩個班輪:

for small_list in big_list: 
    small_list.sort(key=lambda x: -sum([y[0] for l in big_list for y in l if y[1] == x[1]])) 

編輯: 甚至一個班輪

[sorted(small_list, key=lambda x: -sum([y[0] for l in big_list for y in l if y[1] == x[1]])) for small_list in big_list] 
+0

請注意,它會計算每個元素的總數,因此@ eumiro的anwer更適合。 – soulcheck 2011-12-22 14:45:27

相關問題