Search code examples
pythonpython-3.xfor-loopstring-concatenation

how to get a nested data from Concatenate values with same keys in a list of dictionaries?


I have all_writing_test_name_data

all_writing_test_name_data=    
      [
          {
            "id": 1,
            "book_name": Math,
            "writing_test_description": "string",
            "subject_id": 1,
            "book_id": 2,
            "writing_test": "string"
          },
          {
            "id": 2,
            "book_name": Math-1,
            "writing_test_description": "string-1",
            "subject_id": 1,
            "book_id": 2,
            "writing_test": "string-1"
          }
        ]

and I want to Concatenate all_writing_test_name_data like this

 [
  {
    "subject_id": 1,
    "writing_items": [
      {
            "id": 1,
            "book_name": Math,
            "writing_test_description": "string",
            "book_id": 2,
            "writing_test": "string"
          },
          {
            "id": 2,
            "book_name": Math-1,
            "writing_test_description": "string-1",
            "book_id": 2,
            "writing_test": "string-1"
          }
    ]
  }
]

i have tried this but i think there is some lacking in the code for this i can't get the desire data

    x=all_writing_test_name_data
    

    # printing original list
    print("The original list is : " + str(x))
    
    import operator
    from functools import reduce
    all_keys = reduce(operator.or_, (d.keys() for d in x))

    bar = {key: [d.get(key) for d in x] for key in all_keys}

    print('bar',bar['writing_test']+bar['writing_test_description'])


    from collections import Counter
    result = Counter()
    for d in x:
        result[d['writing_test']] = d['writing_test']
        result[d['writing_test_description']] = d['writing_test_description']
    print(result)

    z=bar['writing_test']+bar['writing_test_description']

    print bar

but I can't get my desire data. how can i get the exact same data,what is the mistake


Solution

  • You can group the input data by the subject_id property of each dict, then re-format that data into the value you want:

    from collections import defaultdict
    
    groups = defaultdict(list)
    for test in all_writing_test_name_data:
        subject_id = test.pop('subject_id')
        groups[subject_id].append(test)
    
    result = [ { 'subject_id' : k, 'writing_items' : v } for k, v in groups.items() ]
    

    Output:

    [
        {
            "subject_id": 1,
            "writing_items": [
                {
                    "id": 1,
                    "book_name": "Math",
                    "writing_test_description": "string",
                    "book_id": 2,
                    "writing_test": "string"
                },
                {
                    "id": 2,
                    "book_name": "Math-1",
                    "writing_test_description": "string-1",
                    "book_id": 2,
                    "writing_test": "string-1"
                }
            ]
        }
    ]
    

    Note that this will alter the value of all_writing_test_name_data (due to the test.pop()). If this is not desired, add

    test = test.copy()
    

    prior to the pop.