-2

Newbie here. Say I do the following:

a = "123"
b = a[1]
a = "abc"

My understanding is that:

  • a is not a string object. "123" is a string object (not sure I'm using "object" word correctly - maybe just "piece of data" or string) created by the first statement to which the name a is assigned.
  • Since it is a string, "123" is immutable.
  • b is a new name that points to a portion of the "123" object (the digit - which is also a string - "2"). b does not refer to a new piece of data copied from "123". it refers to the same "2" as the one referred to by a[1].
  • the third statement changes the assignment of the name a to a brand new, immutable string. the old string is not changed. in any way whatsoever. only the name a has been changed.
  • python is automatically garbage collected, which means it frees up memory as data is no longer needed.

See here and here for previous SO discussion about Python's memory model and variables.

So now assuming the above is correct I have a couple questions about this situation:

  1. Since the data that was referred to by a[0] and a[2] is no longer needed after line 3, is it a candidate and/or likely to be garbage collected? Or, since b is still referring to a portion of "123", is the entire string preserved until no names are pointing to any piece it?

    I'm wondering about this because if for example you have a very large list object, and the only remaining names pointing to it use only a small portion of it and no names point to the entire thing, it seems like this could become a big problem for memory management.

  2. If the string does exist in memory until there are no names pointing to any part of it, is there some way to get back at other parts of the string once there are no names for it? In the example above: once a has been reassigned to a new string, and b is pointing to "2", is there a way to get back the "1" and the "3"?

    I am not asking because I actually want to do this, it's just a learning exercise.

Community
  • 1
  • 1
Rick
  • 43,029
  • 15
  • 76
  • 119
  • 4
    Your third bullet is incorrect; `b` is assigned to a *new string object* – jonrsharpe Oct 27 '14 at 12:35
  • I stand corrected. So `b = a` would *not* create a new string object. But `b = a[1]` does create a new string object. – Rick Oct 27 '14 at 12:38
  • What makes you say that? `b = a` *does not* create a new object, `b = a[1]` *does*. – jonrsharpe Oct 27 '14 at 12:39
  • I had it backwards; corrected now. And the same true for all objects, e.g. lists? `a = [1,2,3]`, `b = a` -> no new list object, `b = a[1:]` -> new list object? How about `b = [0:len(a)]`? – Rick Oct 27 '14 at 12:44
  • Why don't you get busy with `a is b` and find out? Note that results for strings and small integers may be counterinutuitive due to interning. – jonrsharpe Oct 27 '14 at 12:45
  • I was unaware if `a is b`. Thanks. – Rick Oct 27 '14 at 12:45
  • `a = [1,2,3]`, `b = a[1]`, `a[1] is b` --> `True`. Is this due to "interning"? – Rick Oct 27 '14 at 12:48
  • This talk by Brandon Rhodes might help you clear up some things about references and garbage collection in Python: [PyOhio 2011: Names, Objects, and Plummeting From The Cliff](http://pyvideo.org/video/542/pyohio-2011-names-objects-and-plummeting-from) – Lukas Graf Oct 27 '14 at 12:49
  • 1
    @RickTeachey `[1,2,3]` is a list object that contains references to separate `int` objects. In some sense, it is more "composite" than a string "123", which is not just a container of the shorter strings `"1"`, `"2"`, and `"3"`. (Unlike C, which does not have a string type and instead provides an API to fake it using arrays of `char` values.) – chepner Oct 27 '14 at 13:01
  • 1
    @RickTeachey no. If `a[1] is 2` would result in `False` that would be how you'd notice interning. See [Python string interning](http://stackoverflow.com/questions/15541404/python-string-interning) for an example. – Lukas Graf Oct 27 '14 at 13:14
  • @chepner This clears things up for me quite a bit. I "knew" that Python doesn't have `char`s, but was still thinking of a string like I would in C++, i.e. a "list" of `char`s. So a string is more like an int in Python than it is a list (viz., it's not a composite), though you can do list-type things with it. Makes sense. – Rick Oct 27 '14 at 13:38
  • @RickTeachey exactly. Strings are immutable in Python, so every operation that results in a different string will *always* result in a new string object. But they do have a somewhat odd property in that they are not a collection type, but nevertheless are iterable. – Lukas Graf Oct 27 '14 at 13:46
  • It's best to keep the concepts "is a collection" and "is iterable" separate. Generators are also iterable, but not collections. – chepner Oct 27 '14 at 13:48

1 Answers1

0

To sum up comments and give an structured explanation:

"123"

is a string object and is immutable. the char at operation ( [x] ) on a string object in Python return a copy of the letter. A single letter is also a string.

a = "123"
b = a[1]

You now have 2 independent string objects "123" and "2". Since b is assigned to an independent string object, changing a will have no effect to b. If you reassign a however, your string object "123" will be lost and there is no way to revive "1" and "3" sorry but you probably already know that.

the list object works differently.

Walle Cyril
  • 3,087
  • 4
  • 23
  • 55