9

I'm trying to teach myself python (and programming in general) and am a little confused about variable assignment. I understand that if I have

>>> a = [1,2,3]
>>> b = a

that b refers to the same object in memory as a does. So if I wanted to create a new list, b, with the same values as a currently has, how would I achieve that?

Also, consider this example:

>>> a = [1, 2, 3]
>>> b = a
>>> x = a[1]
>>> a[1] = 4
>>> print a, b, x
[1, 4, 3] [1, 4, 3] 2

I see from this example, that x is a new object but b points to a. Could someone explain to me what is going on here, why x is a new object but b isn't?

Davin Tryon
  • 66,517
  • 15
  • 143
  • 132
Alex
  • 507
  • 1
  • 5
  • 7
  • I don't think it's a duplicate. – ely Mar 27 '14 at 17:34
  • That answers the first question about how to create the new list. Thanks! The second question is the one really confusing me though. – Alex Mar 27 '14 at 17:35
  • If this is not a duplicate, it may be too broad. What's specifically going on here has more to do with the treatment of lists and integers and the way Python internally represents them than with how it resolves assignment. If we had to go over very data type, it could get long-winded indeed. – Two-Bit Alchemist Mar 27 '14 at 17:36
  • No, it's not about integers. – ely Mar 27 '14 at 17:36
  • I'm pretty sure the second question is the difference between a value type and a reference type and how python deals with the two. – Davin Tryon Mar 27 '14 at 17:36
  • 2
    The difference here is that `a` is a `list`, which is mutable (i.e. can be changed in place), but `a[1]` is an `int`, which is immutable (i.e. can't be changed in place). `a[1] = 4` *replaces* `2` with `4` in the list, but `x` is still pointing to the `2`. – jonrsharpe Mar 27 '14 at 17:37
  • Something like http://www.jeffknupp.com/blog/2013/02/14/drastically-improve-your-python-understanding-pythons-execution-model/ might help you understand what's going on with this example, and explain some related concepts. – Rory Yorke Mar 27 '14 at 17:56

4 Answers4

1

The answer to the second question is that when you x = a[1] x is pointing to the object that is in a[1], not a[1].

When you change a[1] you change the object that a[1] is pointing to, not the object itself. However, x is still pointing to the old object.

I hope that I explained that clearly. If not comment.

EDIT: Exactly what @jonrsharpe said.

Anton
  • 2,282
  • 26
  • 43
1

Consider this example:

In [20]: a = [[1], [2], [3]]

In [21]: b = a

In [22]: x = a[1]

In [23]: a
Out[23]: [[1], [2], [3]]

In [24]: b
Out[24]: [[1], [2], [3]]

In [25]: x
Out[25]: [2]

In [26]: a[1][0] = 4

In [27]: a
Out[27]: [[1], [4], [3]]

In [28]: b
Out[28]: [[1], [4], [3]]

In [29]: x
Out[29]: [4]

The difference here is that when we tinkered around with a[1] we did so by modifying it instead of telling a[1] to refer to a whole new thing.

In your case, when you told x to refer to whatever a[1] refers to, it picked up a reference to some concrete thing, whatever was in a[1] at the time, in your case a specific integer.

Later when you told a[1] to change, it did change. But the thing it used to refer to did not stop existing (because x was still there referring to it).

By saying x = a[1] you are not saying x shall always refer to whatever a[1] refers to.

You are saying x shall refer to whatever a[1] refers to at this moment of assignment.

The same is true for b also, it's just that the "concrete" thing that b was told to refer to was a whole list -- which can having changing contents.

Another example:

a = [1, 2, 3,]
b = a

print a, b

# Prints
#[1, 2, 3]
#[1, 2, 3]

a = [4, 5, 6]

print a, b

# Prints
#[4, 5, 6]
#[1, 2, 3]
ely
  • 74,674
  • 34
  • 147
  • 228
1

The difference here is that a is a list, which is mutable (i.e. can be changed in place), but a[1] is an int, which is immutable (i.e. can't be changed in place). a[1] = 4 replaces 2 with 4 in the list, but x is still pointing to the 2. -@jonrsharpe

b = a[:]

Will create a clone of a that is a different object. We do this because lists are mutable, so when we are technically taking a section of another list like we are here, it can refer to a new object.

anon582847382
  • 19,907
  • 5
  • 54
  • 57
0

I am also new to python. Based on what I understood so far everything in python is an object and variables are mere references to these objects.

So b = a means b points to the same object as a.

However there are two types of objects mutable and immutable. List is a mutable object, meaning the actual list referenced by a and b in your code can be modified. Hence you see that when you make a change to a you are effectively changing the underlying list this changing b as well.

To create an entirely new list b, you can use b=a[:]

haraprasadj
  • 1,059
  • 1
  • 8
  • 17