Related
This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 9 years ago.
When you pass a collection like list, array to another function in python, does it make a copy of it, or is it just a pointer?
Python passes references-to-objects by value.
Python passes references-to-objects by
value (like Java), and everything in
Python is an object. This sounds
simple, but then you will notice that
some data types seem to exhibit
pass-by-value characteristics, while
others seem to act like
pass-by-reference... what's the deal?
It is important to understand mutable
and immutable objects. Some objects,
like strings, tuples, and numbers, are
immutable. Altering them inside a
function/method will create a new
instance and the original instance
outside the function/method is not
changed. Other objects, like lists
and dictionaries are mutable, which
means you can change the object
in-place. Therefore, altering an
object inside a function/method will
also change the original object
outside.
Thing is, the whole reference/value concept won't fit into python. Python has no "value" of a variable. Python has only objects and names that refer to objects.
So when you call a function and put a "name" inside the parenthesis, like this:
def func(x): # defines a function that takes an argument
... # do something here
func(myname) # calling the function
The actual object that myname is pointing is passed, not the name myname itself. Inside the function another name (x) is given to refer to the same object passed.
You can modify the object inside the function if it is mutable, but you can't change what the outside name is pointing to. Just the same that happens when you do
anothername = myname
Therefore I can answer your question with:
it is "pass by value" but all values are just references to objects.
Answers here have been helpful, but I find the need to exhibit this fine distinction which I haven't seen covered, which I've proven to myself with the subsequent CL experiment:
An immutable object ALONE CANNOT be changed within a function call. (answers so far have said that much...)
BUT, an immutable object CONTAINED WITHIN a mutable object CAN be re-assigned within a method call.
'num' does not change here because it is an immutable Number object [supports my point 1.]:
>>> def incr_num(num):
num += 1
>>> num = 0
>>> num
0
>>> incr_num(num)
>>> num
0
list[0] here is an immutable Number object also.
>>> def incr_list(list):
list[0] += 1
>>> list = [0]
>>> list[0]
0
>>> incr_list(list)
>>> list[0]
1
So how did list[0], being an immutable Number object, change (supports my point 2.) while the above example's Number object 'num' did not? The immutable Number object list[0] is contained within the mutable list object 'list', while 'num' from the 1st example is just a non-contained Number object (immutable).
Although well-intended, I feel #Stephen Pape top-rated answer (quoted below), and some other similar ones, were not totally correct (and that motivated me to write this answer):
Some objects, like strings, tuples, and numbers, are immutable.
Altering them inside a function/method will create a new instance and
the original instance outside the function/method is not changed.
My 2nd code experiment above shows a Number object ('list[0]') being altered within a method, and then the original instance outside the function changed.
A reference is passed, but if the parameter is an immutable object, modifying it within the method will create a new instance.
The object is passed. Not a copy, but a reference to the underlying object.
By reference:
>>> x = [0,1,2,3]
>>> def foo(x_list):
x_list[0] = 1
>>> foo(x)
>>> x
[1, 1, 2, 3]
I would also recommend looking at the copy module:
Python documentation for copy
It will help you to understand the underlying issues and how to use it to perform your own deep copy.
Please let me give a humble example
def swap(a, b):
x = a
print id(x)
print id(a)
print id(b)
a = b
print id(a)
b = x
print id(b)
a[0]= '20'
var1 = ['1','2','3','4']
var2 = ['5','6','7','8','9']
print id(var1)
print id(var2)
swap(var1, var2)
print id(var1)
print id(var2)
print var1
print var2
which produces the following result
28329344 var1
28331264 var2
28329344 x
28329344 a
28331264 b
After a = b
28331264 a
after b = x
28329344 b
after return
28329344 var1
28331264 var2
['1', '2', '3', '4']
['20', '6', '7', '8', '9']
Mapping to the memory addresses
28329344 28331264
var1 var2
a b
x
After a=b
a
After b=x
b
After a[0] = '20'
[0] = '20'
After return
['1','2','3','4'] ['20', '6', '7', '8', '9']
This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 9 years ago.
When you pass a collection like list, array to another function in python, does it make a copy of it, or is it just a pointer?
Python passes references-to-objects by value.
Python passes references-to-objects by
value (like Java), and everything in
Python is an object. This sounds
simple, but then you will notice that
some data types seem to exhibit
pass-by-value characteristics, while
others seem to act like
pass-by-reference... what's the deal?
It is important to understand mutable
and immutable objects. Some objects,
like strings, tuples, and numbers, are
immutable. Altering them inside a
function/method will create a new
instance and the original instance
outside the function/method is not
changed. Other objects, like lists
and dictionaries are mutable, which
means you can change the object
in-place. Therefore, altering an
object inside a function/method will
also change the original object
outside.
Thing is, the whole reference/value concept won't fit into python. Python has no "value" of a variable. Python has only objects and names that refer to objects.
So when you call a function and put a "name" inside the parenthesis, like this:
def func(x): # defines a function that takes an argument
... # do something here
func(myname) # calling the function
The actual object that myname is pointing is passed, not the name myname itself. Inside the function another name (x) is given to refer to the same object passed.
You can modify the object inside the function if it is mutable, but you can't change what the outside name is pointing to. Just the same that happens when you do
anothername = myname
Therefore I can answer your question with:
it is "pass by value" but all values are just references to objects.
Answers here have been helpful, but I find the need to exhibit this fine distinction which I haven't seen covered, which I've proven to myself with the subsequent CL experiment:
An immutable object ALONE CANNOT be changed within a function call. (answers so far have said that much...)
BUT, an immutable object CONTAINED WITHIN a mutable object CAN be re-assigned within a method call.
'num' does not change here because it is an immutable Number object [supports my point 1.]:
>>> def incr_num(num):
num += 1
>>> num = 0
>>> num
0
>>> incr_num(num)
>>> num
0
list[0] here is an immutable Number object also.
>>> def incr_list(list):
list[0] += 1
>>> list = [0]
>>> list[0]
0
>>> incr_list(list)
>>> list[0]
1
So how did list[0], being an immutable Number object, change (supports my point 2.) while the above example's Number object 'num' did not? The immutable Number object list[0] is contained within the mutable list object 'list', while 'num' from the 1st example is just a non-contained Number object (immutable).
Although well-intended, I feel #Stephen Pape top-rated answer (quoted below), and some other similar ones, were not totally correct (and that motivated me to write this answer):
Some objects, like strings, tuples, and numbers, are immutable.
Altering them inside a function/method will create a new instance and
the original instance outside the function/method is not changed.
My 2nd code experiment above shows a Number object ('list[0]') being altered within a method, and then the original instance outside the function changed.
A reference is passed, but if the parameter is an immutable object, modifying it within the method will create a new instance.
The object is passed. Not a copy, but a reference to the underlying object.
By reference:
>>> x = [0,1,2,3]
>>> def foo(x_list):
x_list[0] = 1
>>> foo(x)
>>> x
[1, 1, 2, 3]
I would also recommend looking at the copy module:
Python documentation for copy
It will help you to understand the underlying issues and how to use it to perform your own deep copy.
Please let me give a humble example
def swap(a, b):
x = a
print id(x)
print id(a)
print id(b)
a = b
print id(a)
b = x
print id(b)
a[0]= '20'
var1 = ['1','2','3','4']
var2 = ['5','6','7','8','9']
print id(var1)
print id(var2)
swap(var1, var2)
print id(var1)
print id(var2)
print var1
print var2
which produces the following result
28329344 var1
28331264 var2
28329344 x
28329344 a
28331264 b
After a = b
28331264 a
after b = x
28329344 b
after return
28329344 var1
28331264 var2
['1', '2', '3', '4']
['20', '6', '7', '8', '9']
Mapping to the memory addresses
28329344 28331264
var1 var2
a b
x
After a=b
a
After b=x
b
After a[0] = '20'
[0] = '20'
After return
['1','2','3','4'] ['20', '6', '7', '8', '9']
This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 9 years ago.
When you pass a collection like list, array to another function in python, does it make a copy of it, or is it just a pointer?
Python passes references-to-objects by value.
Python passes references-to-objects by
value (like Java), and everything in
Python is an object. This sounds
simple, but then you will notice that
some data types seem to exhibit
pass-by-value characteristics, while
others seem to act like
pass-by-reference... what's the deal?
It is important to understand mutable
and immutable objects. Some objects,
like strings, tuples, and numbers, are
immutable. Altering them inside a
function/method will create a new
instance and the original instance
outside the function/method is not
changed. Other objects, like lists
and dictionaries are mutable, which
means you can change the object
in-place. Therefore, altering an
object inside a function/method will
also change the original object
outside.
Thing is, the whole reference/value concept won't fit into python. Python has no "value" of a variable. Python has only objects and names that refer to objects.
So when you call a function and put a "name" inside the parenthesis, like this:
def func(x): # defines a function that takes an argument
... # do something here
func(myname) # calling the function
The actual object that myname is pointing is passed, not the name myname itself. Inside the function another name (x) is given to refer to the same object passed.
You can modify the object inside the function if it is mutable, but you can't change what the outside name is pointing to. Just the same that happens when you do
anothername = myname
Therefore I can answer your question with:
it is "pass by value" but all values are just references to objects.
Answers here have been helpful, but I find the need to exhibit this fine distinction which I haven't seen covered, which I've proven to myself with the subsequent CL experiment:
An immutable object ALONE CANNOT be changed within a function call. (answers so far have said that much...)
BUT, an immutable object CONTAINED WITHIN a mutable object CAN be re-assigned within a method call.
'num' does not change here because it is an immutable Number object [supports my point 1.]:
>>> def incr_num(num):
num += 1
>>> num = 0
>>> num
0
>>> incr_num(num)
>>> num
0
list[0] here is an immutable Number object also.
>>> def incr_list(list):
list[0] += 1
>>> list = [0]
>>> list[0]
0
>>> incr_list(list)
>>> list[0]
1
So how did list[0], being an immutable Number object, change (supports my point 2.) while the above example's Number object 'num' did not? The immutable Number object list[0] is contained within the mutable list object 'list', while 'num' from the 1st example is just a non-contained Number object (immutable).
Although well-intended, I feel #Stephen Pape top-rated answer (quoted below), and some other similar ones, were not totally correct (and that motivated me to write this answer):
Some objects, like strings, tuples, and numbers, are immutable.
Altering them inside a function/method will create a new instance and
the original instance outside the function/method is not changed.
My 2nd code experiment above shows a Number object ('list[0]') being altered within a method, and then the original instance outside the function changed.
A reference is passed, but if the parameter is an immutable object, modifying it within the method will create a new instance.
The object is passed. Not a copy, but a reference to the underlying object.
By reference:
>>> x = [0,1,2,3]
>>> def foo(x_list):
x_list[0] = 1
>>> foo(x)
>>> x
[1, 1, 2, 3]
I would also recommend looking at the copy module:
Python documentation for copy
It will help you to understand the underlying issues and how to use it to perform your own deep copy.
Please let me give a humble example
def swap(a, b):
x = a
print id(x)
print id(a)
print id(b)
a = b
print id(a)
b = x
print id(b)
a[0]= '20'
var1 = ['1','2','3','4']
var2 = ['5','6','7','8','9']
print id(var1)
print id(var2)
swap(var1, var2)
print id(var1)
print id(var2)
print var1
print var2
which produces the following result
28329344 var1
28331264 var2
28329344 x
28329344 a
28331264 b
After a = b
28331264 a
after b = x
28329344 b
after return
28329344 var1
28331264 var2
['1', '2', '3', '4']
['20', '6', '7', '8', '9']
Mapping to the memory addresses
28329344 28331264
var1 var2
a b
x
After a=b
a
After b=x
b
After a[0] = '20'
[0] = '20'
After return
['1','2','3','4'] ['20', '6', '7', '8', '9']
This question already has answers here:
Immutable vs Mutable types
(18 answers)
Closed 7 years ago.
I wonder why reference variable(dict, list) is accessible from nested function while simple object is not.
In [1]: a = 1
In [2]: b = [1]
In [3]: c = {"c" : 1}
In [4]:
In [4]: def f():
...: a = 2
...: b[0] = 2
...: c["c"] = 2
...:
In [5]: f()
In [6]:
In [6]: print a
1
In [7]: print b
[2]
In [8]: print c
{'c': 2}
Integer is immutable, that means when python execute
a=2 inside f()
It create a new local object. While list and dictionary is mutable, so it can be modified in place.
>>> a = 0
>>> id(a)
31367908
>>> ls = [1,2]
>>> id(ls)
50082760
>>> def f():
a = 2
print id(a)
ls[0] = 5
print id(ls)
>>> f()
31367884
50082760
With statement a = 2 you are creating new local variable with value 2. However when you modify b[0] or c['c'] you are mutating global variable. If you have to deal with mutable types in function (work with them as with local variables) you have to initialize appropriate variable before mutating it:
def f():
c = {}
b = []
c['c'] = 2
b.append(1)
See Variables and scope chapter with great description of how scope works in python and get more info about mutable and immutable types.
This question already has answers here:
How are tuples unpacked in for loops?
(8 answers)
Closed 9 years ago.
I'm new to python and trying to work my way through http://yuji.wordpress.com/2011/06/22/python-imaplib-imap-example-with-gmail/ which has the following line:
result, data = mail.uid('search', None, "ALL") # search and return uids instead
Could someone explain this line?
Thank you.
It means that the function you have called returns an iterable, and the index 0 of the iterable is assigned to x and the index 1 is assigned to y. This is called tuple unpacking.
Eg)
>>> def func(a,b):
... return b,a
...
>>> a = 5
>>> b = 7
>>> a,b = func(a,b)
>>> a
7
>>> b
5
>>> x = func(a,b)
>>> x
(5, 7)
Edit to show that returning multiple values, they are packed as tuple by default and then unpacked at the other end. Since there is only one variable x here, the tuple is assigned to x.
Simple function for swapping two variables(Just for an example) that answers your question
At least, as of python 2.7.x, the function will unpack a tuple of 2 arguments returned from a function. If it returns anything other than 2 arguments in the tuple, I believe it will throw an error if you try to unpack more than this. If it returns 3 arguments and you unpack 2, for example, you will get an exception.
For example:
def func(a):
return (a,a+1,a*2)
a,b,c = func(7)
print a,b
==> 7 8 # NOTE Values
a = func(3)
print a
==> (3, 4, 6) # NOTE: TUPLE
a,b = func(9)
print a,b
==> Exception - ValueError: too many values to unpack
This may be different in 3.0+.
The other answer, that "the function you have called returns an iterable" is a good one. That is what is happening in your specific example. This is what is called "unpacking" in python. The following are examples of unpacking and assignment related to your question:
>>> a,b = 1,2
>>> a
1
>>> b
2
>>> a,b,c = ['do', 're', 'mi']
>>> a
'do'
>>> b
're'
>>> c
'mi'
>>>
This is one of the pretty features of Python syntax. If I am not mistaken, it is also optimized - i.e. the fastest way to achieve the result.