3

Using Python 3.4 and working through examples in a book by O'Reily. The example shows:

A = ['spam']
B = A
B[0] = 'shrubbery'

Result after running print A:

'shrubbery'

Now my thought process is thatA was defined but never changed.

This example yields a different result

A = 'string'
B = A
B = 'dog'

This is the result after running print A:

'string'

Can someone explain?

Vexoids
  • 63
  • 1
  • 7
  • For more on the details of Python internal memory model that underlie all of this, I recommend Wesley Chun's presentation on [Understanding Python’s Memory Model & Mutability](http://cdn.oreillystatic.com/en/assets/1/event/95/Python%20103_%20Memory%20Model%20_%20Best%20Practices%20Presentation.pdf) which he referenced in an [answer to a classic SO question](http://stackoverflow.com/a/2573965/3155195). Particularly page 9 onwards is exactly about this issue. – zehnpaard Jan 04 '15 at 09:25
  • Link to [video of the same presentation](https://ep2013.europython.eu/conference/talks/python-103-mmmm-understanding-pythons-memory-model-mutability-and-methods) for the more audio-visually inclined. – zehnpaard Jan 04 '15 at 09:31

6 Answers6

4

In the first example, you are modifying the list referenced by B.

Doing:

B[0] = 'shrubbery'

tells Python to set the first item in the list referenced by B to the value of 'shrubbery'. Moreover, this list happens to be the same list that is referenced by A. This is because doing:

B = A

causes B and A to each refer to the same list:

>>> A = ['spam']
>>> B = A
>>> A is B
True
>>>

So, any changes to the list referenced by B will also affect the list referenced by A (and vice-versa) because they are the same object.


The second example however does not modify anything. Instead, it simply reassigns the name B to a new value.

Once this line is executed:

B = 'dog'

B no longer references the string 'string' but rather the new string 'dog'. The value of A meanwhile is left unchanged.

0

enter image description here

I hope you could understand it with this way :-)

As you see in first method, both of them refers to same list, second one different.So in second way changes not effects on another one.

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
  • 2
    @NoMorePuppies I think it's a good explanation but I also think purely-graphical answers are not acceptable in SO - they are not searchable and not repeatable, and don't respect accessibility standards – Jivan Jan 04 '15 at 06:56
0

As is the case in most modern dynamic languages, variables in python are actually references which are sort of like C pointers. This means that when you do something like A = B (where A and B are both variables), you simply make A point to the same location in memory as B.

In the first example you are mutating (modifying) an existing object in place -- this is what the variable_name[index/key] = value syntax does. Both A and B continue to point at the same thing, but this things first entry is now 'shrubbery', instead of 'spam'.

In the second example, you make B point at a different (new at this point) object when you say B = 'dog'.

imalison
  • 335
  • 3
  • 8
0

Mutable objects are Lists while Strings are immutable that's why you can change the memory address and the lists itself but not the string.

Gentrit
  • 51
  • 1
0

We are talking here about shared references and mutable / immutable objects . When you do B = A, both variables points to same memory address ( shared reference) . First case , list is a mutable object ( it's state can be change ) but object memory address remains the same . So if you change it's state , then the other variable will see those changes as it points to same memory address .( A and B have same value as they point to same object in memory ) Second case , string is immutable ( you cannot change it ) .By doing B = 'dog' , basically you create another object and now B points to another object ( another memory address ) . In this case A still points to same old memory reference ( A and B have different values )

-2

Here are the differences between the two:

enter image description here

enter image description here

Here's a step by step analysis:

A = ['spam']
"A points to a list whose first element, or A[0], is 'spam'."
B = A
"B points to what A points to, which is the same list."
B[0] = 'shrubbery'
"When we set B[0] to 'shrubbery', the result can be observed in the diagram.
A[0] is set to 'shrubbery' as well."
print (A):



A = 'string'
"A points to 'string'."
B = A
"B points to what A points to, which is 'string'."
B = 'dog'
"Oh look! B points to another string, 'dog', now.
So does what A points to change? No."
The result can be observed in the diagram.
print (A):
Jobs
  • 3,317
  • 6
  • 26
  • 52
  • There are no "primitive types" in Python. All values are objects. This is purely a matter of name binding. – kindall Jan 04 '15 at 06:29
  • @kindall Please see if my answer is now correct. Thanks for pointing that out! I kept thinking Java... – Jobs Jan 04 '15 at 06:33
  • In the second case, A and B are still pointers to string objects. They do not themselves have values. All variables in Python store references to objects. – kindall Jan 04 '15 at 06:34
  • Bad wording... Let me make some corrections. @kindall – Jobs Jan 04 '15 at 06:35
  • @kindall How about now? – Jobs Jan 04 '15 at 06:42
  • You're still storing the strings "in" variables, as if they were somehow different from he lists. – kindall Jan 04 '15 at 06:43
  • Well the left side is the global frame, as in an environmental diagram, and the right side are the objects created. @kindall – Jobs Jan 04 '15 at 06:45
  • @Steve you're still showing an answer which is totally "uncrawlable" and unfindable by any search engine, and which is not possible to display via a non-gui browser - not to tell that it's a wrong answer or that I don't understand the point of adding pictures to make your point, but perhaps some text could be added too, with pictures in support (rather than the other way around) – Jivan Jan 04 '15 at 06:45
  • @Jivan Okay hold on, let me add some descriptions. – Jobs Jan 04 '15 at 06:48
  • @kindall I'll add some clarifications. – Jobs Jan 04 '15 at 06:49
  • Thanks. Hope it makes more sense now. @Jivan – Jobs Jan 04 '15 at 07:02
  • @Jobs You're obviously using Pythontutor. In that case, if you really want to understand the layout, please select "render all object on the heap" instead of "inline primitives". As has been pointed out, Python has no primitives in that sense anyway. – Veky May 28 '19 at 07:01