Home > Software engineering >  Move multiple items in a list to index
Move multiple items in a list to index

Time:06-04

I have a list with dictionaries inside it that looks like this:

testList = [{'title': 'test1', 'path': ['a', 'b']},
{'title': 'test2', 'path': ['a', 'b']}, 
{'title': 'test3', 'path': ['a', 'e']}, 
{'title': 'test4', 'path': ['a', 'e']}, 
{'title': 'test5', 'path': ['a', 'z']}, 
{'title': 'test6', 'path': ['a', 'z']}]

I want to move every dictionary, that has path[-1] == "z" in front of test2. I am trying to make it so my program is able to find the index of the last element in the list with path[-1] == "b", and add it in front of there.

Expected output:

[{'title': 'test1', 'path': ['a', 'b']},
{'title': 'test2', 'path': ['a', 'b']}, 
{'title': 'test5', 'path': ['a', 'z']}, 
{'title': 'test6', 'path': ['a', 'z']},
{'title': 'test3', 'path': ['a', 'e']}, 
{'title': 'test4', 'path': ['a', 'e']}]

I tried to do this:

for d in testList:
    if d['path'][-1] == "b":
        idx = testList.index(d)
    if d['path'][-1] == "z":
        testList.remove(d)
        testList.insert(idx, d)

But this did not work, it simply did not change the list at all. Could someone please provide some help.

CodePudding user response:

As the comments indicate, changing the elements of list while you are iterating through it , it seems to me that you are simply sorting. First everything with b, then everything with z and then everything else.

If we create a sort key like this:

sortkey = {'b' : 0 , 'z' : 1} 

and use it like this:

testList = sorted(testList, key =  lambda x: sortkey.get(x['path'][-1],2))

testlist is now:

[{'title': 'test1', 'path': ['a', 'b']},
 {'title': 'test2', 'path': ['a', 'b']},
 {'title': 'test5', 'path': ['a', 'z']},
 {'title': 'test6', 'path': ['a', 'z']},
 {'title': 'test3', 'path': ['a', 'e']},
 {'title': 'test4', 'path': ['a', 'e']}]

CodePudding user response:

If I guess correctly what you're trying to achieve you can setup a custom sort order

order= ['b','z']

sortedList = sorted(testList, key=lambda x: order.index(x['path'][-1]) if x['path'][-1] in order else len(order))

CodePudding user response:

Try this.

testList = [{'title': 'test1', 'path': ['a', 'b']},
{'title': 'test2', 'path': ['a', 'b']}, 
{'title': 'test3', 'path': ['a', 'e']}, 
{'title': 'test4', 'path': ['a', 'e']}, 
{'title': 'test5', 'path': ['a', 'z']}, 
{'title': 'test6', 'path': ['a', 'z']}]

index = [i for i,v in enumerate(testList) if v['title'] == 'test2'][-1] 1 # find the index of dict with the title of test2 and add 1.


new_lst = []

for a in testList:
    if a['path'][-1] == 'z':
        new_lst.insert(index,a)
        index =1
        continue
    new_lst.append(a)


print(new_lst)

CodePudding user response:

Find the last dictionary in the list with a 'b' value. Create a new list comprised of the elements up to and including the element previously found. Subsequently either insert or append to the new list.

No sorting here because the check for 'z' is assumed to be arbitrary.

testList = [{'title': 'test1', 'path': ['a', 'b']},
            {'title': 'test2', 'path': ['a', 'b']},
            {'title': 'test3', 'path': ['a', 'e']},
            {'title': 'test4', 'path': ['a', 'e']},
            {'title': 'test5', 'path': ['a', 'z']},
            {'title': 'test6', 'path': ['a', 'z']}]

idx = -1

for i, d in enumerate(testList):
    if d['path'][-1] == 'b':
        idx = i 

if (idx := idx 1) > 0:
    newList = testList[:idx]
    for d in testList[idx:]:
        if d['path'][-1] == 'z':
            newList.insert(idx, d)
            idx  = 1
        else:
            newList.append(d)
    print(newList)

Output:

[{'title': 'test1', 'path': ['a', 'b']}, {'title': 'test2', 'path': ['a', 'b']}, {'title': 'test5', 'path': ['a', 'z']}, {'title': 'test6', 'path': ['a', 'z']}, {'title': 'test3', 'path': ['a', 'e']}, {'title': 'test4', 'path': ['a', 'e']}]
  • Related