Discussion:
[Tutor] python dictionaries (copy by reference or copy by value?)
Alex McFerron
2015-05-02 23:25:41 UTC
Permalink
trying to understand why this is true

step 1: x = {}
step 2: y = x
step 3: x['key'] = 'value'
# at this point if i print x or y i see {'key', 'value'}
step 4: x['key'] = 'newValue' #and at this point printing x or y i see
{'key', 'newValue'} and this is true if this was y['key']

because of the behavior in step 4, i'm thinking, ok the copy job from step
2 was a pointer only and not a by value copy job. fair enough

step 5: x = {} #or y={}
step 6: print both. and what i get here is that x will be empty but y will
not (or visa verse)

question: if y=x from step 2 (the copy job) is just creating a pointer y
that points to the same thing as x then why when i set x = {} in step 5
does that also not cause y to equal {}?

what am i not understanding about python dictionaries?
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Alan Gauld
2015-05-03 00:01:59 UTC
Permalink
Post by Alex McFerron
step 1: x = {}
step 2: y = x
step 3: x['key'] = 'value'
# at this point if i print x or y i see {'key', 'value'}
step 4: x['key'] = 'newValue' #and at this point printing x or y i see
{'key', 'newValue'} and this is true if this was y['key']
because of the behavior in step 4, i'm thinking, ok the copy job from step
2 was a pointer only and not a by value copy job. fair enough
First mistake is to think of step 2 as a "copy job" its not.
Python variables do not work like variables in C and other
similar languages. see below.
Post by Alex McFerron
step 5: x = {} #or y={}
step 6: print both. and what i get here is that x will be empty but y will
not (or visa verse)
question: if y=x from step 2 (the copy job) is just creating a pointer y
that points to the same thing as x then why when i set x = {} in step 5
does that also not cause y to equal {}?
what am i not understanding about python dictionaries?
a = 42
b = a
a = 66
print a,b # => 66,42
The same behaviour.
Remember that unlike some other languages you may have used
variables are not bits of memory. They are labels that are
used as keys in a dictionary. Its a bit like sticking
a post-it note onto a physical object. Many notes can be
stuck to the same object. And you can take a note off an
object and stick it on a new one.

So in step 1 you take a new post-it, write the name 'x'
on it and attach it to your dictionary.
Then in step 2 you do not copy anything, rather you get
another post-it and write the name 'y' on it, then you
stick it to the same dictionary object as x

In step 5 you move the first post-it, with 'x' on it, to a
new object. It just happens to be another dictionary, but
it could have been anything. But the post-it with 'y' on is
still stuck to the original dictionary object.

Does that help?
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Ben Finney
2015-05-03 01:18:16 UTC
Permalink
Post by Alex McFerron
trying to understand why this is true
step 1: x = {}
Assignment; binds a reference (the name ‘x’) to a newly-created empty
dictionary.
Post by Alex McFerron
step 2: y = x
Assignment; binds a reference (the name ‘y’) to the object currently
referred to by ‘x’. That's the same object as above.
Post by Alex McFerron
step 3: x['key'] = 'value'
Assignment; binds a reference (the item keyed by the string ‘'key'’ in
the same dictionary as above) to the string object ‘'value'’.
Post by Alex McFerron
# at this point if i print x or y i see {'key', 'value'}
Because there's only one dictionary in all of this.
Post by Alex McFerron
step 4: x['key'] = 'newValue'
Assignment; binds a reference, the same reference as before (the item
keyed by the string ‘'key'’ in the same dictionary as above) to the
string object ‘'newValue'’.
Post by Alex McFerron
#and at this point printing x or y i see {'key', 'newValue'} and this
is true if this was y['key']
Because there's only one dictionary in all of this.
Post by Alex McFerron
because of the behavior in step 4, i'm thinking, ok the copy job from
step 2 was a pointer only and not a by value copy job. fair enough
None of these operations are copies. Assignment in Python is *never* a
copy operation.
Post by Alex McFerron
step 5: x = {}
Assignment; binds a reference (the name ‘x’) to a newly created empty
dictionary.
Post by Alex McFerron
step 6: print both. and what i get here is that x will be empty but y will
not (or visa verse)
Because the name ‘y’ is still a reference to the original dictionary above.
Post by Alex McFerron
question: if y=x from step 2 (the copy job)
There's your error. Assignment in Python *never* copies, it only binds a
reference to some value.
--
\ “If you continue running Windows, your system may become |
`\ unstable.” —Microsoft, Windows 95 bluescreen error message |
_o__) |
Ben Finney

_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python
Steven D'Aprano
2015-05-03 02:32:15 UTC
Permalink
Post by Alex McFerron
trying to understand why this is true
[...]
Post by Alex McFerron
question: if y=x from step 2 (the copy job) is just creating a pointer y
that points to the same thing as x then why when i set x = {} in step 5
does that also not cause y to equal {}?
what am i not understanding about python dictionaries?
Python, like most modern languages, is neither copy-by-value nor
copy-by-reference.

Python uses *exactly* the same name-binding mechanism for all values,
regardless of type, and all names, whether they are global variables,
function parameters, or anything else.

I discuss this question as it applies to function arguments here:

http://import-that.dreamwidth.org/1130.html

but the same reasoning applies to any other assignment. The important
thing to remember is that

y = x

doesn't make a copy of x, it just makes y refer to the same object as x
currently refers to. This is *not the same* as making y refer to x
(that is, y and x are permanently linked to be alternative names for
the same variable). Can you see the difference? If not, I'm happy to
respond with more detail.
--
Steve
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Loading...