-2

I have a list of dictionaries like this`

[
    {
      "account_name": "Rounded Off (Purchase)",
      "amount": 0.28,
      "doc_date": "2023-04-05",
      "doc": "P.Inv.-1",
      "date_created": "2023-04-05T15:30:42.964203"
    },
    {
      "account_name": "Discount (Purchase)",
      "amount": 100,
      "doc_date": "2023-04-05",
      "doc": "P.Inv.-1",
      "date_created": "2023-04-05T15:30:42.964203"
    },
    {
      "account_name": "Discount (Purchase)",
      "amount": 86.4,
      "doc_date": "2023-04-05",
      "doc": "P.Inv.-1",
      "date_created": "2023-04-05T15:30:42.964203"
    }
  ]`

I would like to simplify the list by adding the "amount" if two dictionaries have the same values for "doc" and "account_name" keys e.g. in this case "account_name" : "Discount (Purchase)" and "doc" : "P.Inv-1".

I can not think of a simple solution without using a lots of placeholder variables and and multiple loops over the list.

The expected result should look like

[
    {
      "account_name": "Rounded Off (Purchase)",
      "amount": 0.28,
      "doc_date": "2023-04-05",
      "doc": "P.Inv.-1",
      "date_created": "2023-04-05T15:30:42.964203"
    },
    {
      "account_name": "Discount (Purchase)",
      "amount": 186.4,
      "doc_date": "2023-04-05",
      "doc": "P.Inv.-1",
      "date_created": "2023-04-05T15:30:42.964203"
    }
]

Any help is greatly appreciated. Thanks.

  • 2
    Would `date_created` and `doc_date` always be the same? If not, how do we pick that? – artemis Apr 06 '23 at 13:35
  • no date_created is the server date and doc_date is the reference date entered by user when an entry /document is created – Sourabh Patel Apr 06 '23 at 13:39
  • 1
    What @artemis is asking is, will `date_created` be the same in both of the `dict`s to merge and if not, which one should be chosen? And the same for `doc_date`. For example, you're merging the last 2 `dict`s in your sample data. In your sample, both of those values are the same in both `dict`s. – Axe319 Apr 06 '23 at 13:43
  • Yes all the dictionaries (entries) belong to a document in this case "P.Inv-1" and the doc date is taken from there so the doc date for all the entries belonging to the document will be same and hence entries are created after the document is created in the same function the date_created for all the entries belonging to a document will also be the same. precedence should be given to doc date – Sourabh Patel Apr 06 '23 at 13:50
  • so far my solution is d_frame = pd.DataFrame.from_dict(list) d_frame = d_frame.groupby(['doc', 'account_name','date_created','doc_date'])['amount'].sum().reset_index().to_dict('records') – Sourabh Patel Apr 06 '23 at 13:55

1 Answers1

1

It often helps to gradually think over such problems, and perhaps use simple pen and paper to understand how our variables will evolve over time. Some little effort now can go a long way mid-long-term.

My approach would be to create an empty list, which is populated every time your two keys are different. If they are the same it updates the amount-value. You might want to decide what happens to "data_created" field, because now I do not examine it at all (Does it keep the first 'data_created' value or the second? Why?) Since you don't provide a reproducible example I would write something as follows:

initial_dictionary_list = [
    {
      "account_name": "Rounded Off (Purchase)",
      "amount": 0.28,
      "doc_date": "2023-04-05",
      "doc": "P.Inv.-1",
      "date_created": "2023-04-05T15:30:42.964203"
    },
    {
      "account_name": "Discount (Purchase)",
      "amount": 100,
      "doc_date": "2023-04-05",
      "doc": "P.Inv.-1",
      "date_created": "2023-04-05T15:30:42.964203"
    },
    {
      "account_name": "Discount (Purchase)",
      "amount": 86.4,
      "doc_date": "2023-04-05",
      "doc": "P.Inv.-1",
      "date_created": "2023-04-05T13:30:42.964203"
    }
  ]

from typing import Dict, List # these provide very helpful type hints

def process_dictionary_list(data: list[dict]) -> list[dict]:
    list_of_dictionaries_with_different_keys = {}
    for dictionary in dictionary_list:
        key = (dictionary['account_name'], dictionary['doc'])
        if key in list_of_dictionaries_with_different_keys:
            list_of_dictionaries_with_different_keys[key]['amount'] += dictionary['amount']
        else:
            list_of_dictionaries_with_different_keys[key] = dictionary.copy()
    return list(list_of_dictionaries_with_different_keys.values())

final_dictionary_list = process_dictionary_list(initial_dictionary_list)

print(final_dictionary_list)
# [{'account_name': 'Rounded Off (Purchase)', 'amount': 0.28, 'doc_date': '2023-04-05', 'doc': 'P.Inv.-1', 'date_created': '2023-04-05T15:30:42.964203'}, {'account_name': 'Discount (Purchase)', 'amount': 186.4, 'doc_date': '2023-04-05', 'doc': 'P.Inv.-1', 'date_created': '2023-04-05T15:30:42.964203'}]
Konstantinos
  • 4,096
  • 3
  • 19
  • 28