Home > Software engineering >  Rearrange list of dictionaries moving elements from another list of dictionaries to head
Rearrange list of dictionaries moving elements from another list of dictionaries to head

Time:01-18

(I am using Python 3.8) The problem is as follows: I have the following data

items = [{season: 3, id: 1}, {season: 5, id: 2}, {season: 10, id: 3}, {season: 8, id:4}]

And I would like to rearrange this list moving to the head the elements from seasons, e.g., 8 and 10. For that, I have another list with the elements from that subset:

items_to_top = [{season: 10, id: 3}, {season: 8, id:4}]

I know this is not the most efficient way to do this, but it has to be like this since I have to respect some interfaces. In order to move them to the top of the former list I am doing

 for item in items_to_top:
    items.remove(item)
    items.insert(0, item)

This operation is safe since items_to_top is extracted from items, therefore is a closed set.

I am looking for a more efficient/faster way to do this since when items grows (around 30k elements) and items_to_top grows as well (around 7k elements) the loop takes close to 1 minute to finish.

I have tried to transform everything to set but I can't since my data is unhashable (dicts) and inside the values of the dicts are also unhashable types (lists).

CodePudding user response:

You can create a set of tuples using the values of your dictionaries and create a new list like so:

top_set = {(d[season], d[id]) for d in items_to_top}
new_items = items_to_top   [d for d in items if (d[season], d[id]) not in top_set]

The problem here is that everytime you use items.insert(0, item) you're creating a new list from scratch. Aditionally, the remove needs to search for the correct value from the beginning to the end of the list.

EDIT: Another approach, since you can't hash all the elements in the dictionaries.

 for item in items_to_top[::-1]:
    items.remove(item)
    items.append(item)

items = items[::-1]

CodePudding user response:

Would it be possible for you to store the indexes of the top items instead (or in addition to) the items_to_top list ?

That would allow a more direct reorganization of the items list using indexing instead of searches.

For example:

items = [{'season': 3, 'id': 1}, {'season': 5, 'id': 2}, 
         {'season': 10, 'id': 3}, {'season': 8, 'id':4}]

toTop = [2,3]

items = [items[i] for i in dict.fromkeys([*toTop,*range(len(items))])]


print(items)
[{'season': 10, 'id': 3}, {'season': 8, 'id': 4}, 
 {'season': 3, 'id': 1}, {'season': 5, 'id': 2}]
  •  Tags:  
  • Related