Home > database >  Python: consolidate list of lists
Python: consolidate list of lists

Time:10-04

I want to consolidate a list of lists (of dicts), but I have honestly no idea how to get it done. The list looks like this:

    l1 = [
          [
           {'id': 1, 'category': 5}, {'id': 3, 'category': 7}
          ],
          [
           {'id': 1, 'category': 5}, {'id': 4, 'category': 8}, {'id': 6, 'category': 9}
          ],
          [
           {'id': 6, 'category': 9}, {'id': 9, 'category': 16}
          ],
          [
           {'id': 2, 'category': 4}, {'id': 5, 'category': 17}
          ]
         ]

If one of the dicts from l1[0] is also present in l1[1], I want to concatenate the two lists and delete l1[0]. Afterwards I want to check if there are values from l1[1] also present in l1[2]. So my desired output would eventually look like this:

new_list = [
             [
               {'id': 1, 'category': 5}, {'id': 3, 'category': 7}, {'id': 4, 'category': 8}, {'id': 6, 'category': 9}, {'id': 9, 'category': 16}
             ],
             [
               {'id': 2, 'category': 4}, {'id': 5, 'category': 17}
             ]
           ]

Any idea how it can be done? I tried it with 3 different for loops, but it wouldnt work, because I change the length of the list and by doing so I provoke an index-out-of-range error (apart from that it would be an ugly solution anyway):

    for list in l1:
        for dictionary in list:
            for index in range(0, len(l1), 1):
                if dictionary in l1[index]:
                    dictionary in l1[index].append(list)
                    dictionary.remove(list) 

Can I apply some map or list_comprehension here? Thanks a lot for any help!

CodePudding user response:

IIUC, the following algorithm works.

  • Initialize result to empty
  • For each sublist in l1:
    • if sublist and last item in result overlap
      • append into last list of result without overlapping items
  • otherwise
    • append sublist at end of result

Code

# Helper functions
def append(list1, list2):
    ' append list1 and list2 (without duplicating elements) '
    return list1   [d for d in list2 if not d in list1]

def is_intersect(list1, list2):
    ' True if list1 and list2 have an element in common '
    return any(d in list2 for d in list1) or any(d in list1 for d in list2)

# Generate desired result
result = []                   # resulting list
for sublist in l1:
    if not result or not is_intersect(sublist, result[-1]):
        result.append(sublist)
    else:
        # Intersection with last list, so append to last list in result
        result[-1] = append(result[-1], sublist)

print(result)

Output

[[{'id': 1, 'category': 5},
  {'id': 3, 'category': 7},
  {'id': 4, 'category': 8},
  {'id': 6, 'category': 9},
  {'id': 9, 'category': 16}],
 [{'id': 2, 'category': 4}, {'id': 5, 'category': 17}]]
​

CodePudding user response:

maybe you can try to append the elements into a new list. by doing so, the original list will remain the same and index-out-of-range error wouldn't be raised.

new_list = []

for list in l1:
    inner_list = []    

    for ...
        if dictionary in l1[index]:
            inner_list.append(list)
            ...
    new_list.append(inner_list)
  • Related