总结元组列表中相同项目的值,而它们是字符串

时间:2016-03-19 20:34:53

标签: python string list tuples

如果我有这样的元组列表:

my_list = [('books', '$5'), ('books', '$10'), ('ink', '$20'), ('paper', '$15'), ('paper', '$20'), ('paper', '$15')] 

如何将列表转为:

[('books', '$15'), ('ink', '$20'), ('paper', '$50')]

即。添加相同项目的费用,而这两个项目都是元组中的字符串。我有价格项目是字符串的问题。任何暗示都将非常感激。非常感谢!

我以这种方式获得第一个列表:

my_list=[]
for line in data:
        item, price  = line.strip('\n').split(',') 
        cost = ["{:s}".format(item.strip()), "${:.2f}".format(float(price))]
        my_list.append(tuple(cost))

现在my_list应如上所示。

5 个答案:

答案 0 :(得分:2)

您可以使用defaultdict执行此操作:

>>> from collections import defaultdict
>>> my_list = [('books', '$5'), ('books', '$10'), ('ink', '$20'), ('paper', '$15'), ('paper', '$20'), ('paper', '$15')] 
>>> res = defaultdict(list)
>>> for item, price in my_list:
...     res[item].append(int(price.strip('$')))
... 
>>> total = [(k, "${}".format(sum(v))) for k, v in res.items()]
>>> total
[('ink', '$20'), ('books', '$15'), ('paper', '$50')]

答案 1 :(得分:0)

使用字典相当容易:

result={} #initialize an empty dictionary
for (type,cost) in my_list:
    if type not in result.keys():
        result[type]=int(cost[1:]) #add entry
    else:
        result[type]=result[type]+int(cost[1:]) #increment cost

#make dictionary a list again
dictlist=[]
for key, value in result.iteritems():
    temp = [key,"$"+str(value)] #add dollar sign
    dictlist.append(temp)

print dictlist

编辑:忘了两行

答案 2 :(得分:0)

您只需使用字典即可​​解决此问题。

my_list = [('books', '$5'), ('books', '$10'), ('ink', '$20'),
       ('paper', '$15'), ('paper', '$20'), ('paper', '$15')]

sums = {}
for item, price in my_list:
    sums[item] = sums.get(item, 0) + int(price[1:])

print sums

如果您需要元组列表,请执行

print sums.items()

为了得到你期望的输出,

print [(item, '$' + str(price)) for item, price in sums.items()]

<强>更新

如果您有浮点价值的费用,您只需将int改为float就可以了,其余代码保持不变,

sums[item] = sums.get(item, 0) + float(price[1:])

答案 3 :(得分:0)

如果您的数据已按照样本输入进行分组,则可以使用itertools.groupby,按元组的每个第一个元素进行分组,并对每个组中的价格求和:

from itertools import groupby
from operator import itemgetter

my_list = [('books', '$5'), ('books', '$10'), ('ink', '$20'), ('paper', '$15'), ('paper', '$20'), ('paper', '$15')]

grouped = [(k, "${}".format(sum(int(s[1][1:]) for s in v)))    
               for k ,v in groupby(my_list, itemgetter(0))]

输出:

[('books', '$15'), ('ink', '$20'), ('paper', '$50')]

如果没有订购,您可以调用已排序的groupby(sorted(my_list), itemgetter(0)),但会将复杂性更改为n log n,因此在这种情况下,dict选项可能会更好。

您也可以在data上执行groupby并忘记构建中间列表,csv.reader也会为您分割数据:

from itertools import groupby
from operator import itemgetter

from csv import reader
grouped = [(k, "${}".format(sum(int(s[1]) for s in v))) 
              for k, v in groupby(reader(data), itemgetter(0))]

当您想要输出时,也可以将值保留为整数和格式。还要处理浮动而不是int:

from csv import reader
grouped = [(k, sum(float(s[1]) for s in v))
              for k, v in groupby(reader(data), itemgetter(0))]

当您想要输出时,您可以添加美元符号并填充,以便您获得格式良好的输出:

In [10]: "${:.2f}".format(1.0)
Out[10]: '$1.00'

答案 4 :(得分:-1)

只是为了好玩,一个单行:

[(k,'$'+str(sum(int(e[1][1:]) for e in my_list if e[0]==k))) for k in set(map(lambda x:x[0], my_list))]

实际上并没有这样做。