atultherajput
atultherajput

Reputation: 175

How to update list with function (with return value) in python

I am implementing few list methods manually like append(), insert(), etc. I was trying to add element at the end of list (like append method). This the working code i am using:

arr = [4,5,6]

def push(x, item): 
  x += [item]
  return x

push(arr,7)
print(arr)      #Output: [4,5,6,7]

But when I am implementing same code with little difference. I am getting different output.

arr = [4,5,6]

def push(x, item): 
  x = x + [item]
  return x

push(arr,7)
print(arr)      #Output: [4,5,6]

And I am facing same for insert method. Here is code for insert method:

arr = [4,5,7,8]

def insert(x, index, item): 
  x = x[:index] + [item] + x[index:]
  return x

insert(arr,2,6)
print(arr)      #Output: [4,5,7,8]

I know I can store return value to the list by arr=insert(arr,2,6) but I want an alternative solution, that list automatically gets update after calling function like in my first code sample.

Edit 1: I think x[index:index] = [item] is better solution for the problem.

Upvotes: 0

Views: 9978

Answers (5)

Ahmad
Ahmad

Reputation: 11

class DerivedList(list):
    def insertAtLastLocation(self,obj):
        self.__iadd__([obj])        

parameter=[1,1,1]
lst=DerivedList(parameter)
print(lst)   #output[1,1,1]
lst.insertAtLastLocation(5)
print(lst)   #output[1,1,1,5]
lst.insertAtLastLocation(6)
print(lst)   #output[1,1,1,5,6]

You can use this code to add one element at last position of list

class DerivedList(list):
    def insertAtLastLocation(self,*obj):
        self.__iadd__([*obj])

parameter=[1,1,1]
lst=DerivedList(parameter)
print(lst)    #output[1,1,1]
lst.insertAtLastLocation(5)
print(lst)     #output[1,1,1,5]
lst.insertAtLastLocation(6,7)
print(lst)    #output[1,1,1,5,6,7]
lst.insertAtLastLocation(6,7,8,9,10)
print(lst)   #output[1,1,1,5,6,7,8,9,10]

This code can add multiple items at last location

Upvotes: -1

Chris
Chris

Reputation: 22963

In your first example you mutated(a.k.a changed) the list object referred to by x. When Python sees x += [item] it translates it to:

x.__iadd__([item])

As you can see, we are mutating the list object referred to by x by calling it's overloaded in-place operator function __iadd__. As already said, __iadd__() mutates the existing list object:

>>> lst = [1, 2]
>>> lst.__iadd__([3])
[1, 2, 3]
>>> lst
[1, 2, 3]
>>> 

In your second example, you asked Python to assign x to a new reference. The referenced now referrer to a new list object made by combining (not mutating) the x and [item] lists. Thus, x was never changed.

When Python sees x = x + [item] it can be translated to:

x = x.__add__([item])

The __add__ function of lists does not mutate the existing list object. Rather, it returns a new-list made by combing the value of the existing list and the argument passed into __add__():

>>> lst = [1, 2]
>>> lst.__add__([3]) # lst is not changed. A new list is returned.
[1, 2, 3]
>>>

You need to return the the result of the version of push to the arr list. The same goes for insert.

Upvotes: 2

Prune
Prune

Reputation: 77857

The problem is that you haven't captured the result you return. Some operations (such as +=) modify the original list in place; others (such as x = x + item) evaluate a new list and reassign the local variable x.

In particular, note that x is not bound to arr; x is merely a local variable. To get the returned value into arr, you have to assign it:

arr = push(arr, 7)

or

arr = insert(arr, 2, 6)

Upvotes: -1

Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard

Reputation: 160497

You can assign to a slice of the list to implement your insert w/o using list.insert:

def insert(x, index, item):
    x[:] = x[:index] + [item] + x[index:]

this replaces the contents of the object referenced by x with the new list. No need to then return it since it is performed in-place.

Upvotes: 1

Scott Hunter
Scott Hunter

Reputation: 49873

x += [item] and x = x + [item] are not a little difference. In the first case, you are asking to make a change to the list referenced by x; this is why the result reflects the change. In the second, you are asking to have x reference a new list, the one made by combining x's original value and [item]. Note that this does not change x, which is why your result is unchanged.

Also note that your return statements are irrelevant, since the values being returned are ignored.

Upvotes: 3

Related Questions