Python Forum
Grouping and sum of a list of objects
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Grouping and sum of a list of objects
#1
Hi,

I have a list of objects with certain attributes: I would like to group them and then calculate the sum of one of their attributes.
I'll try to explain better with an example:


from itertools import groupby
from dataclasses import dataclass

@dataclass
class Mine():
    number: int
    material: str
    production: float
    um: str     # Unit of measure
    activity: bool

@dataclass 
class Total_Production():
    material: str
    tot_production: float
    um: str     # Unit of measure

def by_material(p):
    return p.material
    
def sum_by_material(mines):
    grouped_prods = []
    for key, group in groupby(sorted(mines, key=by_material), by_material):
        tot = 0
        for g in group:
            tot += g.production 
        grouped_prods.append(Total_Production(key, tot, g.um))
    return grouped_prods
This works fine, but I would like to calculate the sum using the relevant built-in function or in general to look for better ideas, I tried to write something like this:

def sum_by_material(mines):
    grouped_prods = []
    for key, group in groupby(sorted(mines, key=by_material), by_material):
        tot = sum(g.production for g in group)
        grouped_prods.append(Total_Production(key, tot, ???))
    return grouped_prods
But of course I lose the information about the unit of measure and I don't know how to add it.


Thank you in advance
Reply
#2
If you are ready to import the well known more_itertools library, you could write
from more_itertools import spy

def sum_by_material(mines):
    grouped_prods = []
    for key, group in groupby(sorted(mines, key=by_material), by_material):
        (mine,), group = spy(group)
        tot = sum(g.production for g in group)
        grouped_prods.append(Total_Production(key, tot, mine.um))
    return grouped_prods
Note that your code assumes that all the mines with a given material use the same unit of measure.

You could also do this, without additional library
def sum_by_material(mines):
    grouped_prods = []
    for key, group in groupby(sorted(mines, key=by_material), by_material):
        mine = next(group)
        tot = sum((g.production for g in group), mine.production)
        grouped_prods.append(Total_Production(key, tot, mine.um))
    return grouped_prods
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Grouping Data based on 30% bracket purnima1 4 1,142 Mar-10-2023, 07:38 PM
Last Post: deanhystad
  Creating list of lists, with objects from lists sgrinderud 7 1,564 Oct-01-2022, 07:15 PM
Last Post: Skaperen
Question Keyword to build list from list of objects? pfdjhfuys 3 1,500 Aug-06-2022, 11:39 PM
Last Post: Pedroski55
  How to store the resulting Doc objects into a list named A xinyulon 1 1,855 Mar-08-2022, 11:49 PM
Last Post: bowlofred
  Grouping and summing of dataset jef 0 1,608 Oct-04-2020, 11:03 PM
Last Post: jef
  Passing List of Objects in Command Line Python usman 7 3,092 Sep-27-2020, 03:45 PM
Last Post: ndc85430
  How to create and define in one line a 2D list of class objects in Python T2ioTD 1 1,989 Aug-14-2020, 12:37 PM
Last Post: Yoriz
  Grouping algorithm riccardoob 7 2,931 May-19-2020, 01:22 PM
Last Post: deanhystad
  Organizing list of objects by attribute scarney1988 3 2,156 Mar-11-2020, 03:55 PM
Last Post: scarney1988
  List of objects with sublist medatib531 4 2,278 Mar-01-2020, 06:16 PM
Last Post: buran

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020