Search code examples
pythonlistterminologydefinition

What is the term to describe this property of how lists work?


I am looking for the proper term to describe this well-known property of collection objects, and more importantly, the way the stack diagram changes when variables are used to reference their elements:

>>> x = 5
>>> l = [x]
>>> x += 1
>>> l
[5]
>>> x
6

What is the name of what the list is doing to the variable x to prevent it from being bound to any changes to the original value of x? Shielding? Shared structure? List binding? Nothing is coming back from a Google search using those terms.

Here's an example with more detail (but doesn't have a definition, unfortunately).

an example of list structure sharing

Credit to ocw.mit.edu


Solution

  • The behavior you're describing has to do with references. If you're familiar with c, you're probably also familiar with "pointers." Pointers in c can get really complicated, and Python uses a data model that greatly simplifies things. But having a bit of background in c helps understand Python's behavior here, which is closely related to the behavior of c pointers. So "pointer," "reference," and "dereference" are all terms that are related to what you're talking about, although none of them is quite a "name" for it. Perhaps the best name for it is "indirection" -- though that's a bit too abstract and inclusive; this is a very specific kind of indirection. Perhaps "reference semantics"? Here's a slide from a talk by GvR himself that uses that term, and a google search turns up a few useful hits.

    But if you don't have any background in c, here's my best explanation. In short, you can think of a Python name as a pointer to an object. So when you assign a name to a value, you're "pointing" that name at the value. Then, when you assign a new value to the name, you point it at a new value; but the old value isn't changed at all as a result. This seems natural when thinking about names as pointers here; the "value of the name" is changed, but the "value of the value" is not.

    The thing that's a bit confusing is that += behaves inconsistently. When you use += on a number, the result makes perfect sense using the above metaphor:

    x = 5
    y = x
    x += 1
    print x, y 
    # 6 5
    

    The behavior is exactly the same as it would be if you did x = x + 1.

    But sometimes += is overloaded in a way that does in-place mutation. It's a pragmatic, but slightly inconsistent, idiom:

    x = [5]
    y = x
    x += [6]
    print x, y
    # [5, 6] [5, 6]
    

    So here, the "value of the value" is changed. This is actually not my favorite thing about Python, but there are good reasons for it.