Ivan
Ivan

Reputation: 333

How to pass a list element as reference?

I am passing a single element of a list to a function. I want to modify that element, and therefore, the list itself.

def ModList(element):
    element = 'TWO'

l = list();
l.append('one')
l.append('two')
l.append('three')
print l
ModList(l[1])
print l

But this method does not modify the list. It's like the element is passed by value. The output is:

['one','two','three']
['one','two','three']

I want that the second element of the list after the function call to be 'TWO':

['one','TWO','three']

Is this possible?

Upvotes: 10

Views: 15969

Answers (4)

jimifiki
jimifiki

Reputation: 5534

In many cases you can also consider to let the function both modify and return the modified list. This makes the caller code more readable:

def ModList(theList, theIndex) :
          theList[theIndex] = 'TWO'
    return theList

l = ModList(l, 1)

Upvotes: 0

KDN
KDN

Reputation: 1399

The explanations already here are correct. However, since I have wanted to abuse python in a similar fashion, I will submit this method as a workaround.

Calling a specific element from a list directly returns a copy of the value at that element in the list. Even copying a sublist of a list returns a new reference to an array containing copies of the values. Consider this example:

>>> a = [1, 2, 3, 4]
>>> b = a[2]
>>> b
3
>>> c = a[2:3]
>>> c
[3]
>>> b=5
>>> c[0]=6
>>> a
[1, 2, 3, 4]

Neither b, a value only copy, nor c, a sublist copied from a, is able to change values in a. There is no link, despite their common origin.

However, numpy arrays use a "raw-er" memory allocation and allow views of data to be returned. A view allows data to be represented in a different way while maintaining the association with the original data. A working example is therefore

>>> import numpy as np
>>> a = np.array([1, 2, 3, 4])
>>> a
array([1, 2, 3, 4])
>>> b = a[2]
>>> b
3
>>> b=5
>>> a
array([1, 2, 3, 4])
>>> c = a[2:3]
>>> c
array([3])
>>> c[0]=6
>>> a
array([1, 2, 6, 4])
>>> 

While extracting a single element still copies by value only, maintaining an array view of element 2 is referenced to the original element 2 of a (although it is now element 0 of c), and the change made to c's value changes a as well.

Numpy ndarrays have many different types, including a generic object type. This means that you can maintain this "by-reference" behavior for almost any type of data, not only numerical values.

Upvotes: 6

JaredPar
JaredPar

Reputation: 754575

Python is a pass by value language hence you can't change the value by assignment in the function ModList. What you could do instead though is pass the list and index into ModList and then modify the element that way

def ModList(theList, theIndex) :
  theList[theIndex] = 'TWO'

ModList(l, 1)

Upvotes: 5

Brendan Long
Brendan Long

Reputation: 54242

Python doesn't do pass by reference. Just do it explicitly:

l[1] = ModList(l[1])

Also, since this only changes one element, I'd suggest that ModList is a confusing name.

Upvotes: 5

Related Questions