python - Modifying a list with existing references to elements? -
(if want skip 2 a.m. python science , cut chase, question summed @ end)
consider following:
1: animals = ['cat', 'cow', 'donkey', 'horse'] # start list 2: animals_reference = animals # make reference , assign animals 3: cat = animals[0] # refer cat first element of animals 4: assert cat animals[0] # no copy occurred, still same object 5: animals[0] = animals[0].capitalize() # change first element of list 6: assert cat not animals[0] # animals[0] refers object 7: assert animals_reference animals # animals still points same object before
my understanding underlying structure of python list c array (with lots of dynamic stuff going on, still, @ end of day, c array.)
what's confusing me this: set cat
refer first element of list (3). in c, that'd referring address of first element of array.
we modify first element of list (5).
but after doing that, cat no longer refers object (6). however, list reference hasn't changed either, since in (7) see has pointed same object since beginning.
this messing mind because suggests cat refers else, though never reassigned.
so performed following experiment:
cat = animals[0] # refer cat first element of animals assert cat animals[0] # no copy occurred, still same object print("id of cat: {}".format(hex(id(cat)))) print("id of animals[0]: {}".format(hex(id(animals[0])))) print("id of animals[]: {}".format(hex(id(animals)))) print("capitalizing animals[0]...") animals[0] = animals[0].capitalize() print("-id of cat: {}".format(hex(id(cat)))) print("-id of animals[0]: {}".format(hex(id(animals[0])))) print("-id of animals[]: {}".format(hex(id(animals))))
with output:
id of cat: 0xffdda580 id of animals[0]: 0xffdda580 id of animals[]: 0xffddc828 capitalizing animals[0]... -id of cat: 0xffdda580 # stayed same! -id of animals[0]: 0xffe12d40 # changed!! -id of animals[]: 0xffddc828
this has led me believe python lists not contiguous elements of memory , changes element point somewhere else in memory? mean, address of first element of array earlier in memory address of array itself!
what underlying structure lists use explains saw?
here's 1 way think it:
1: animals = ['cat', 'cow', 'donkey', 'horse'] # start list 2: animals_reference = animals # make reference , assign animals 3: cat = animals[0] # refer cat first element of animals
this not make cat
refer "the first element of animals", @ least not in way seem mean. makes cat
refer whatever first element of animals refers to. in case, string "cat". in other words, expression animals[0]
reference object. object string cat
. when animals[0]
, object expression animals[0]
refers to. when cat = animals[0]
, set cat
refer object.
there no way avoid "dereferencing" value animals[0]
. is, there no way "give me pointingness of animals[0]
when animals[0]
starts pointing @ else, new variable point @ else". can animals[0]
refers to, not referring-ness itself.
thus:
4: assert cat animals[0] # no copy occurred, still same object 5: animals[0] = animals[0].capitalize() # change first element of list
here change animals[0]
points at. set cat
animals[0]
used point at. cat
, animals[0]
point @ different things. string "cat"
did not change (which why is
test still shows values same); it's animals[0]
stopped pointing @ string , started pointing @ string "cat"
instead.
Comments
Post a Comment