0

I have a question about references in c++ and its overlap to python. I have written a function in python that takes in x and y and adds y to x. Thereafter, I print the outcome.

def func(x, y):
    x = x + y
    return x

c = [5,4,6,4]
d = [6,7,8,9]
t = func(c,d)
print(t)
print(c)

As python passes everything by reference, one would expect that the variable c would change and contain d. However, this is not the case. To see if this also holds true for c++, I have written a vector function that adds two vectors together.

vector<int> FuncAdd(vector<int> &x, vector<int> &y){

x.insert(x.end(), y.begin(), y.end());

return x;
}

int main(){
vector<int> y = {3,4,5,6};
vector<int> x = {4,5,6,7};
vector<int> c = FuncAdd(x, y);

for(int i : x){  
    cout << i << " ";
}
cout << endl;
for(int i : c){  
    cout << i << " ";
}
cout << endl;

The outcome here is that x does change and now contains y. Why does c++ change the vector and python does not change its list? Thanks!

  • Because they are 2 different languages. They behaves differently. Also in python it is more likely acts as a pointer not a reference. So you are not changing c. It should be something like: `def func(x, y): \ [x.append(i) for i in y]` then you actually change c. – simre May 15 '22 at 11:16
  • That explains it, thanks! –  May 15 '22 at 11:23
  • 2
    "As python passes everything by reference" Python *never*, *ever* passes *anything* by reference. Here's a challange: write a function, `swap(x, y)` that in will swap two variables in *any context*, e.g. `a = 0, b = 99; swap(a, b); print(a, b)` would print `99 0` instead of `0 99`. You can't. But this is trivially possible in a language that supports call by reference (like C++ does). Note, Python is also not call by value, since arguments to a function are not copied – juanpa.arrivillaga May 19 '22 at 05:09
  • Read the accepted answer here: https://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference – juanpa.arrivillaga May 19 '22 at 05:10

3 Answers3

2

In Python, when you use + for concatenating two lists a new list is created and returned. This means that when you wrote x + y, a new list is created. This also means that after x = x + y, the local variable x will now refer to the newly created list(as a result of x + y). If you want to change the original list in-place you could instead use the extend method as explained in the below example.

#--------v--v------------->x and y are local variables that refer to the passed objects
def func(x, y):
    
#-------vvvvv------------->this x + y creates a new list
    x = x + y
#---^--------------------->the "local variable x" on the left hand side now refers to the new list object created as a result of x + y
    return x

c = [5,4,6,4]
d = [6,7,8,9]


t = func(c,d) #here t refers to the object returned by the call to func which essentially was created from x + y 
print(t)      #prints the object return by the call to func [5, 4, 6, 4, 6, 7, 8, 9]
print(c)      #prints c which still refers to the original list [5, 4, 6, 4]

Note instead of writing x = x + y and then returning x you could just have written return x + y and the effect will be the same, as shown below:

#--------v--v------------->x and y are local variables that refer to the passed objects
def func(x, y):

    return x +y #creates and returns a new list object

c = [5,4,6,4]
d = [6,7,8,9]


t = func(c,d) #here t refers to the object returned by the call to func which essentially was created from x + y 
print(t)      #prints the object return by the call to func [5, 4, 6, 4, 6, 7, 8, 9]
print(c)      #prints c which still refers to the original list [5, 4, 6, 4]

If you want to change the original list in-place you can use list's extend method as shown below:

#--------v--v------------->x and y are local variables that refer to the passed objects
def func(x, y):
#-----vvvvvv-------------->changes x in-place instead of creating a new list
    x.extend(y); 

c = [5,4,6,4]
d = [6,7,8,9]

#no need to do the assignment here because the changes made to the list inside func will be reflected in the original list as we have used extend method
func(c,d) 
print(c)      #prints c [5, 4, 6, 4, 6, 7, 8, 9]

Similarly, in C++ you're using the std::vector::insert member function of std::vector that will insert the elements into the vector on which the member function was called(which is the vector x). And since you've passed the vector x by reference, the change will be reflected in the original vector.

Jason
  • 36,170
  • 5
  • 26
  • 60
0

Yes it's true, in Python when you call a function you get a reference to the same object that was in the caller. If you modify that object, you'll see that modification after the function returns.

But the statement x = x + y does not modify x, it creates a brand new reference x that replaces the old one from that point of the function onwards.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
0

In python Object references are passed by value.

So your list is an object [5,4,6,4] and you gave it the name 'c'

When you pass variable c to a function, the object is passed by value but it will be the same object.

So x is a different variable but contains the same object, until...

You assign x with another object i.e. x+y Now x has a different object, not the same as what c has

Thats why, append() would work because it is essentially an operation on the same object.

Refer to below link if it is still unclear Python pass by value or reference

Sohit Gore
  • 438
  • 1
  • 5
  • 13