2013-04-21 85 views
0

我有一個這樣的名單在python:Python的列表中的分組由

list1 = [('a', 6.5),('a', 6.5),('a', -6.5),('b', 0.0),('b', 0.0),('b',6.5),('b', -6.5)('b',6.5)] 

我需要它包含一個列表:

[(a,avg(6.5,6.5,-6.5),no.of_occurences_of_a),(b,avg(0.0,6.5,-6.5,6.5),no.of_occurences_of_b)] 

[(a,6.5/3,3)(b,6.5/4,4)] 

如何做到這一點?

+0

您的要求輸出[(a,6.5/3,3)(b,6.5/4,4)]或[(a,6.5/3,3),(b,6.5/4,4)]? – Johnny 2013-04-21 19:36:01

回答

3

您可以使用itertools.groupby

In [19]: list1 = [('a', 6.5),('a', 6.5),('a', -6.5),('b', 0.0),('b', 0.0),('b',6.5),('b', -6.5),('b',6.5)] 

In [20]: from itertools import groupby 

In [21]: from operator import itemgetter 

In [22]: lis=[] 

In [23]: for k,v in groupby(list1,key=itemgetter(0)): 
    items=[x[1] for x in v] 
    lis.append((k, sum(items)/len(items), len(items))) 
    ....:  

In [24]: lis 
Out[24]: [('a', 2.1666666666666665, 3), ('b', 1.3, 5)] 

注意,以防list沒有排序你已經先解決它使用itertools.groupby來得到想要的結果。

使用collections.defaultdict,這會爲未排序的項目工作,以及:

In [25]: from collections import defaultdict 

In [26]: dic=defaultdict(list) 

In [27]: for k,v in list1: 
    ....:  dic[k].append(v) 
    ....:  

In [28]: dic 
Out[28]: defaultdict(<type 'list'>, {'a': [6.5, 6.5, -6.5], 'b': [0.0, 0.0, 6.5, -6.5, 6.5]}) 

In [29]: [(k,sum(v)/len(v),len(v)) for k,v in dic.items()] 
Out[29]: [('a', 2.1666666666666665, 3), ('b', 1.3, 5)] 
+0

這假定所有分組元素都是連續出現的。如果輸入列表被混洗,您需要先對其進行排序。 – 2013-04-21 19:25:22

+0

謝謝你完美的作品 – 2013-04-21 19:25:52

+0

@poorsod你是對的,我已經添加了一個筆記抵消。 – 2013-04-21 19:29:34

1

使用itertools.groupby。通常它會一直一行代碼,但它在你的情況有點麻煩,因爲你需要消費羣體的兩倍,以獲得平均長度:

list1 = [('a', 6.5), ('a', 6.5), ('a', -6.5), ('b', 0.0), 
     ('b', 0.0), ('b', 6.5), ('b', -6.5), ('b',6.5)] 

import itertools 
import operator 

fst = operator.itemgetter(0) 
snd = operator.itemgetter(1) 
result = [] 
for grouper, group in itertools.groupby(sorted(list1, key=fst), key=fst): 
    items = map(snd, group) 
    result.append((grouper, sum(items)/len(items), len(items))) 
1

醜陋的解決方案(不正確格式化爲您要求的):

list1 = [('a', 6.5),('a', 6.5),('a', -6.5),('b', 0.0),('b', 0.0),('b',6.5),('b', -6.5),('b',6.5)] 

a_list = [] 
b_list = [] 
a = 0 
b = 0 
for item in list1: 
    if 'a' in item: 
     a_list.append(item[1]) 
     a += 1 
    if 'b' in item: 
     b_list.append(item[1]) 
     b +=1 

#a is now the count of a's 
#b is now the count of b's 
a_avarage = reduce(lambda x, y: x + y, a_list) 
b_avarage = reduce(lambda x, y: x + y, b_list)