2013-05-20 107 views
4

假設我有以下列表中的元組:蟒蛇和元組列表基於元組的第一個值

myList = [(0,2),(1,3),(2,4),(0,5),(1,6)] 

我想基於相同的第一個元組值來總結這個名單:

[(n,m),(n,k),(m,l),(m,z)] = m*k + l*z 

對於myList

sum = 2*5 + 3*6 = 28 

我怎麼能得到這個?

+5

你的問題不是特別清楚如何計算輸出...... – root

+1

爲什麼沒有與(2,4)元素髮生任何事情?如果第一個元組值出現3次或更多次,您希望發生什麼? – wim

+1

對不起,我英文很差。對於這些元組,如果它們具有相同的第一個字段,則將它們的第二個字段相乘。忽略不具有相同第一個字段的元組。最後總結多個值。 – stephenlee

回答

4

可以使用collections.defaultdict

>>> from collections import defaultdict 
>>> from operator import mul 
>>> lis = [(0,2),(1,3),(2,4),(0,5),(1,6)] 
>>> dic = defaultdict(list) 
>>> for k,v in lis: 
    dic[k].append(v) #use the first item of the tuple as key and append second one to it 
...  

#now multiply only those lists which contain more than 1 item and finally sum them. 
>>> sum(reduce(mul,v) for k,v in dic.items() if len(v)>1) 
28 
+0

+1優雅的解決方案 – jamylak

0
from operator import itemgetter 
from itertools import groupby 

def mul(args): # will work with more than 2 arguments, e.g. 2*3*4 
    return reduce(lambda acc, x: acc*x, args, 1) 

myList = [(0,2),(1,3),(2,4),(0,5),(1,6)] 
sorted_ = sorted(myList, key=itemgetter(0)) 
grouped = groupby(sorted_, key=itemgetter(0)) 
numbers = [[t[1] for t in items] for _, items in grouped] 
muls = [mul(items) for items in numbers if len(items) > 1] 
print sum(muls) 
+1

這裏不需要排序,這可以在'O(N)'中完成。來自'groupby'的 –

+0

文檔:「一般來說,迭代器需要按照相同的鍵功能排序」 –

+1

好的,現在我收到您的評論。同意。而不是「在這裏不需要排序」,它應該是「不需要在這裏排序和groupby :) :) –

0

將該溶液做它在相對於所述多個可讀defaultdict版本採用兩個通行證和可能會佔用更多空間的單程:

myList = [(0,2),(1,3),(2,4),(0,5),(1,6)] 
sum_ = 0 
once, twice = {}, {} 
for x, y in myList: 
    if x in once: 
     sum_ -= twice.get(x, 0) 
     twice[x] = twice.get(x, once[x]) * y 
     sum_ += twice[x] 
    else: 
     once[x] = y 


>>> sum_ 
28 
0

即使您有多個輸入,並且不只有兩個輸入相同的密鑰,也可以使用以下程序

#!/usr/local/bin/python3 

myList = [(0,2),(1,3),(2,4),(0,5),(1,6),(1,2)] 

h = {} 
c = {} 
sum = 0 

for k in myList: 
     # if key value already present 
     if k[0] in c: 
       if k[0] in h: 
         sum = sum - h[k[0]] 
         h[k[0]] = h[k[0]] * k[1] 
       else: 
         h[k[0]] = c[k[0]] * k[1] 
       sum = sum + h[k[0]] 
     else: 
       # stores key and value if first time though the loop 
       c[k[0]] = k[1]     
print('sum is' + str(sum))