Home > Back-end >  How to insert an element in a list after using del in python
How to insert an element in a list after using del in python

Time:05-14

def my_len(lst):
    mylen = 0
    for i in lst:
        mylen  = 1
    return mylen

def insrt(lst, what, where):
    length = my_len(lst)
    tmp = [0] * (length   1)
    for i in range(0, where):
        tmp[i] = lst[i]
    tmp[where] = what
    for i in range(where, length   1):
        tmp[i] = lst[i - 1]
    return tmp

def move(lst, from_index, to_index):
    a = lst[from_index]
    del lst[from_index]
    insrt(lst, a, to_index)
    return lst

my intention was if the original list input is [1, 2, 3, 4, 5, 6], then print(move(lst, 3, 1) will give [1, 4, 2, 3, 5, 6], but my code gives [1, 2, 3, 5, 6]. Please explain how to fix it.

CodePudding user response:

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]

CodePudding user response:

This would work,

def move(lst, from_index, to_index):
  new_lst = lst[:to_index]   [lst[from_index]]   [item for item in lst[to_index:]]
  new_lst.pop(from_index   1)
  return new_lst

lst = [1, 2, 3, 4, 5, 6]
move(lst, 3, 1)

Output -

[1, 4, 2, 3, 5, 6]

CodePudding user response:

The main problem you're seeing right now relates to how your insrt function works, as compared to how you're calling it.

The way you've written it, insert returns a new list containing the values from the old list plus one new value at a particular index. But when you call it in move, you seem to be expecting it to modify the given list in place. It doesn't do that. You need to change at least one of the two functions so that they match up. Either make insrt work in-place, or make move save the value returned by it rather than throwing it away.

Anyway, here's a very simple tweak to your move function that makes it work properly with the insrt function as you've shown it:

def move(lst, from_index, to_index):
    a = lst[from_index]
    del lst[from_index]
    new_lst = insrt(lst, a, to_index)       # save the new list after the insert
    return new_lst                          # and then return it

I'd note that using del on the earlier line already modifies the lst passed in, so this design may not make a whole lot of sense. You might want to modify insrt to work in place instead, to be consistent. That would look something like this (which would work with your original move):

def insrt(lst, what, where):
    length = my_len(lst)
    lst.append(None)                      # add a dummy value at the end of the list
    for i in range(length-1, where, -1):  # iterate backwards from the end
        lst[i] = lst[i - 1]               # shift each value back
    lst[where] = what                     # plug in the new value
    # no return any more, this version works in place
  • Related