NB. See the end of the answer for an alternative interpretation of the move
If you want the item to end up in the defined to_index, you can simply use list.insert and list.pop:
def move(lst, from_index, to_index):
lst.insert(to_index, lst.pop(from_index))
examples:
l = [1, 2, 3, 4, 5, 6]
move(l, 1, 3)
print(l)
[1, 3, 4, 2, 5, 6]
l = [1, 2, 3, 4, 5, 6]
move(l, 3, 1)
print(l)
[1, 4, 2, 3, 5, 6]
l = [1, 2, 3, 4, 5, 6]
move(l, 3, 3)
print(l)
[1, 2, 3, 4, 5, 6]
NB. your function should probably either return a copy, or modify the list in place, not both. (here I chose to modify in place, see below for a variant).
copy variant:
def move(lst, from_index, to_index):
lst = lst.copy()
lst.insert(to_index, lst.pop(from_index))
return lst
l = [1, 2, 3, 4, 5, 6]
l2 = move(l, 1, 3)
print(l)
[1, 2, 3, 4, 5, 6]
print(l2)
[1, 3, 4, 2, 5, 6]
alternative interpretation: move to the position as defined before the move
In this different interpretation, the item moves to the position as defined if the insertion occured before the deletion.
In this case we need to correct the insertion position if it is greater than the initial position.
We can take advantage of the boolean/integer equivalence by subtracting to_index>from_index (1 if True, 0 otherwise)
def move(lst, from_index, to_index):
lst.insert(to_index-(to_index>from_index), lst.pop(from_index))
l = [1, 2, 3, 4, 5, 6]
move(l, 1, 3)
print(l)
# [1, 3, 2, 4, 5, 6]