To sum up values of same items in a list of tuples while they are string

后端 未结 5 693
一整个雨季
一整个雨季 2021-01-23 01:56

If I have list of tuples like this:

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


        
5条回答
  •  感情败类
    2021-01-23 02:37

    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:

    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.

    You can also do the groupby on data and forget building an intermediary list, csv.reader will also split the data for you:

    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:

    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'
    

提交回复
热议问题