[英]To sum up values of same items in a list of tuples while they are string
If I have list of tuples like this:如果我有这样的元组列表:
my_list = [('books', '$5'), ('books', '$10'), ('ink', '$20'), ('paper', '$15'), ('paper', '$20'), ('paper', '$15')]
how can I turn the list to this:我怎样才能把列表变成这个:
[('books', '$15'), ('ink', '$20'), ('paper', '$50')]
ie to add the expense of same item while both the items are string in the tuples.即添加相同项目的费用,而这两个项目都是元组中的字符串。 I have problem with the price items being string.我对价格项目是字符串有问题。 Any hint would be greatly appreciated.任何提示将不胜感激。 Thanks a lot!非常感谢!
I am getting the first list in this way:我以这种方式获得第一个列表:
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))
Now my_list
should look like given above.现在my_list
应该像上面给出的那样。
You can use defaultdict
to do this:您可以使用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')]
This is fairly easy using a dictionary:这很容易使用字典:
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
Edit: forgot two lines编辑:忘了两行
You can simply use a dictionary to solve this problem.你可以简单地使用字典来解决这个问题。
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
And if you need list of tuples, just do如果您需要元组列表,只需执行
print sums.items()
And to get your the output you expect,为了得到你期望的输出,
print [(item, '$' + str(price)) for item, price in sums.items()]
Update更新
If you have costs with floating point value, you can simply change int
to float
like this and rest of the code remains the same,如果您有浮点值的成本,您可以像这样简单地将int
更改为float
并且其余代码保持不变,
sums[item] = sums.get(item, 0) + float(price[1:])
If your data is already grouped like you sample input, you can use itertools.groupby , grouping by each first element of the tuples and summing the prices in each group:如果您的数据已经像您输入的样本一样分组,您可以使用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))]
Output:输出:
[('books', '$15'), ('ink', '$20'), ('paper', '$50')]
If it were not ordered you could call sorted groupby(sorted(my_list), itemgetter(0))
but changes the complexity to n log n
so a dict option may be better in that case.如果没有排序,您可以调用 sorted groupby(sorted(my_list), itemgetter(0))
但将复杂性更改为n log n
因此在这种情况下 dict 选项可能更好。
You can also do the groupby on data
and forget building an intermediary list, csv.reader
will also split the data for you:你也可以对data
csv.reader
而忘记建立一个中间列表, 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))]
You might be better also leaving the values as ints and formatting when you want to output.当您想要输出时,您最好也将值保留为整数和格式。 Also to handle floats cast to float not int:还要处理浮点数转换为浮点数而不是 int:
from csv import reader
grouped = [(k, sum(float(s[1]) for s in v))
for k, v in groupby(reader(data), itemgetter(0))]
When you want to output you can add the dollar sign and also pad so you get nicely formatted output:当您想输出时,您可以添加美元符号并填充,以便获得格式良好的输出:
In [10]: "${:.2f}".format(1.0)
Out[10]: '$1.00'
Just for fun, a one-liner:只是为了好玩,单行:
[(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))]
Don't actually do this.实际上不要这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.