0

I have a list of objects and i want to group them based on two properties. Every "action" object has a "task" and "date" property and i want to create one "Aggregation" object for each combination of task/date, that aggregates every "action" which suits that condition.

However, i believe my code is inefficient and i think maybe some kind of map reduce function would be better here? (I don't really know, i'm asking)

REPRODUCIBLE EXAMPLE:

class Action():
    def __init__(self, date, task):
        self.date = date
        self.task = task

action_1 = Action('2020/01/01', '1')
action_2 = Action('2020/01/02', '1')
action_3 = Action('2020/01/01', '1')
action_4 = Action('2020/01/01', '1')

# In reality i'll have a list of multiple actions with multiple date/task values

REPRODUCIBLE EXAMPLE OUTPUT

expected_result = [ object1 , object2 ]

object1.actions = [action1, action3, action4]
object2.actions = [action2]

# Every object can only contain actions with the same date/task

MY CURRENT SOLUTION:

class Agregation():
    def __init__(self, actions = []):
        self.actions = actions

    # Some methods i will use in the future
def splitDivision(actions):
    result = {}

    for action in actions:
        task = action.task
        date = action.date

        if not date in result:
            result[date] = {}
        if not task in result[date]:
            result[date][task] = Agregation(date, task)

        result[date][task].actions.append(action)

    return list(x for date in result.values() for x in date.values())

For example, the above code works. However i think that using nested dictionaries on the "splitDivision" function is not really pythonic..

What should i change here?

Ricardo Vilaça
  • 846
  • 1
  • 7
  • 18

1 Answers1

0

Your question is quite confusing for me, but is this what you want?

inst = []
class Action():
    def __init__(self, date, task):
        self.date = date
        self.task = task
        inst.append(self)

action_1 = Action('2020/01/01', '1')
action_2 = Action('2020/01/02', '1')
action_3 = Action('2020/01/01', '1')
action_4 = Action('2020/01/01', '1')


actions_list = list(sorted(set([(x.date,x.task) for x in inst])))
class Agregation():
    def __init__(self, ):
        
        object1_actions = [x for x in inst if (x.date,x.task) == actions_list[0]]
        object2_actions = [x for x in inst if (x.date,x.task) == actions_list[1]]
        
        print(object1_actions)
        print(object2_actions)

Do note if you want the name of the class, when you're adding the objects to a list, you need to pass in the name when making that object

coderoftheday
  • 1,987
  • 4
  • 7
  • 21
  • thanks for your effort but it seems my problem got completely misunderstood.. :( i don't know what to do to explain it better but it seems that my solution is good enough for now. I mean that every combination of date/task values of an "action" object should be inside of a separate aggregation "object" automatically. But nevermind :) It was my bad for not being concise with my explanations.. – Ricardo Vilaça Nov 25 '20 at 02:52