0
b = [0]

def copyalist(b):
    b = [1, 2, 3]
    print(b)

copyalist(b)
print(b)

The outputs are below:

[1, 2, 3]
[0]

The first line indicates that in the function, b was set to [1, 2, 3]; However, when you print(b) out of the function,the second output says that b is still [0].

I don't understand that, why the outer b is not changed?

I also tried b = copy.deepcopy([1, 2, 3]), the outputs are the same.

However, the following code works well:

b = [0]

def copyalist(b):
    b += [1, 2, 3]
    print(b)

copyalist(b)
print(b)

The outputs are below:

[0, 1, 2, 3]
[0, 1, 2, 3]
DirtyBit
  • 16,613
  • 4
  • 34
  • 55
  • Because in your first example, your funciton does not return any thing, just prints a list that you defined inside it, once the call comes back it print the original `b` list which had `[0]`. Nothing magic in it. Nothing being copied either. – DirtyBit Apr 04 '19 at 13:03
  • In your second snippet, again you are only concatenating/merging the list with the previous one. nothing being copied. – DirtyBit Apr 04 '19 at 13:04
  • 2
    You have two entirely unrelated variables named `b`: a global one, and a local one inside `copyalist()`. The local `b`'s initial value is the same as the global `b`, but that changes once you assign a new value to the local `b`. – jasonharper Apr 04 '19 at 13:05
  • Possible duplicate of [How do I pass a variable by reference?](https://stackoverflow.com/questions/986006/how-do-i-pass-a-variable-by-reference) – Bram Vanroy Apr 04 '19 at 13:06
  • Make sure you undertand the difference between global and local variables. In addition, it is not a good practice to alter globals inside the function scope. – Tarifazo Apr 04 '19 at 13:07
  • Your question seems to come down to two things. Pass by reference and pass by value; and mutable and immutable types. I suggest to read into that, as well as the linked duplicate. – Bram Vanroy Apr 04 '19 at 13:07

4 Answers4

0

In python, lists are passed as function arguments only by reference, i.e., only the memory address of the first element is given. When defining a new b inside the function, you just change the position in memory to which the inner variable b refers, but the outer b still points to the original position. Vice versa, when you do b += [1, 2, 3], you change the content inside the cell referenced by the inner b and, since inner and outer b point to the same cells, it reflects in a change of the outer b as well.

Gianluca Micchi
  • 1,584
  • 15
  • 32
0
b = copyalist(b) 

and return b in the function

def copyalist(b):
    b = [1, 2, 3]
    return(b)

When you are defining something in a function it is only used inside that function.

elvar333
  • 1
  • 2
0

This code:

def copyalist(b):
    b = [1, 2, 3]
    print(b)

will only mean to remap the variable name b to a new list, but not modifying the original b. If you mean to modify the original list, you have to explicitly tell Python to replace the actual content. The way to do is:

def copyalist(b):
    b[:] = [1, 2, 3]
    print(b)
adrtam
  • 6,991
  • 2
  • 12
  • 27
0

This is due to a difference in global and local variables. You can add global to your function to get the desired result.

b = [0]

def copyalist():
    global b
    b = [1, 2, 3]
    print(b)

copyalist()
print(b)

OUTPUT

[1, 2, 3]
[1, 2, 3]

A more in depth summary is here

AG-W
  • 70
  • 1
  • 10