0

I have some experience in C, and having some trouble understanding Python's way of handling names (identifiers). As I understand it, declaring a list x = [1, 2] and then declaring a new label y = x, I seem to be actually making x as the pointer, and y, also a pointer, holds the same address as x. But in Python we are calling this labeling (these are different concepts?).

The same system happens with: x = 5 and y = x. Where x is now a label for an integer, 5, and y is a label for 5 as well. But now when I change x it turns out y will not change. So in the latter case, I do not think x or y are pointers in that sense. Are x and y on the stack as opposed to the heap? If so, how do I know which one they are? Is applying knowledge of the stack and heap useless in this situation, perhaps even detrimental? I am really confused about this part of the language, thank you for helping.

Leonardo
  • 1,452
  • 3
  • 15
  • 26

1 Answers1

3

Python does not have "pointers", and it does not have "variables", and it does not have "assignment". Instead it binds object references to names; but we still call the operation performed by the = statement "assignment" to simplify things.

When you perform y = x, you bind the name y to the reference contained in x (or vice versa; the distinction is unimportant). The difference in how they are handled depends on the further operations performed upon it.

x = []          # A new list object is bound to x
y = x           # The reference bound to x is bound to y as well
x.append(None)  # None is *appended* to the list object bound to `x`
print y         # y is bound to the same list
x = 5           # x is *rebound* to a different object
print y         # y remains bound to the list
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • The thing confusing me most is why the same thing does not happen for `x = 5` and then `y = x` They are different objects now? Why not for lists? Or is it the `5` that is what cannot be changed, and this is the reason... ah that gives me a headache, maybe I don't need to know. – Leonardo Aug 22 '13 at 08:01
  • 1
    @Leonardo No, they are the same object. What is different between `[]` and `5` is that `5` is **immutable**, hence every operation on `5` creates a *new* object, while this isn't true for lists. – Bakuriu Aug 22 '13 at 08:03
  • @Bakuriu Ah thank you, for obliterating the confusion that was the part I needed to know! – Leonardo Aug 22 '13 at 08:04
  • @Leonardo: `x = x + [None]` would also create and bind a new object. – Ignacio Vazquez-Abrams Aug 22 '13 at 08:07
  • @IgnacioVazquez-Abrams Yes, but that's not true for `x += [None]`, while `x += 5` *does* create a new object. Reading the question I believe Leonardo found this difference between lists and integers. – Bakuriu Aug 22 '13 at 08:08
  • @IgnacioVazquez-Abrams You just brought the headache back.. Why will `x` change and `y` will not, if `y = x` with your example `x += [None]` – Leonardo Aug 22 '13 at 08:09
  • 1
    That's dependent on the type of object bound to x though, and not strictly speaking its mutability. – Ignacio Vazquez-Abrams Aug 22 '13 at 08:10
  • @IgnacioVazquez-Abrams But when I do `x.append(None)` we have a difference now.. It is because I used a mutator? And you use assignment, which 'creates' new objects.. I think I see it. – Leonardo Aug 22 '13 at 08:11
  • 1
    Mutating an object does not rebind it. Rebinding a name does not mutate either object. – Ignacio Vazquez-Abrams Aug 22 '13 at 08:12
  • @IgnacioVazquez-Abrams So when `x = x + [None]` occurs, garbage collection deletes the old thing `x` aliased.. I am guessing is what you mean by "Rebinding a name does not mutate either object" That took me a second to process though and I probably do not make much sense, but cant explain it anyway. – Leonardo Aug 22 '13 at 08:15
  • GC does not necessarily happen, but the refcount of the object previously bound to `x` is decremented. – Ignacio Vazquez-Abrams Aug 22 '13 at 08:16