Slices time complexity

Oscar Benjamin oscar.j.benjamin at gmail.com
Tue May 19 10:18:54 EDT 2015


On 19 May 2015 at 09:50, Chris Angelico <rosuav at gmail.com> wrote:
> On Tue, May 19, 2015 at 6:39 PM, Marko Rauhamaa <marko at pacujo.net> wrote:
>> For example, you could explain Python's object references as pointers
>> (memory addresses) if you considered that helpful. (That's how Lisp
>> textbooks often explain cons cells.)
>
> Sorta-kinda-maybe, but if a C programmer's idea of pointers is invoked
> to explain Python's object references, the differences will start to
> be problematic:
>
> 1) Pointer arithmetic simply doesn't exist in Python. Arrays/lists are
> not just pointers to their first elements, and subscripting is most
> definitely NOT "add to pointer and dereference".
> 2) In fact, dereferencing as a whole isn't really a 'thing' either. At
> best, it happens automatically.
> 3) References actually mean something. Copying a pointer doesn't.
> Whether the Python you're using is refcounted (CPython) or
> mark-and-sweep (uPy, I think) or some other model, an additional
> reference to the same object will prevent it from being disposed of,
> which isn't the case in C.
> 4) A pointer is itself a value. You can pass a
> pointer-to-local-variable to another function and have that function
> change a local variable.

I think this is actually one of those areas where the analogy does
make sense. In Python if I pass an object as an argument to another
function I can mutate the object but I can't rebind the name in the
parent frame. Similarly in C I can pass a pointer to anything into
another function and the other function will be able to mutate the
pointed-to variable but not change the value of the pointer in the
parent frame.

int b = 2;

void f(int* d)
{
    *d = 3; // Changes a which is pointed to by c and d.
    d = &b; // Doesn't affect c.
    *d = 4;  // Changes b
}

int main(int argc, char *argv[])
{
    int a = 1;
    int *c = &a;  // a and *c are the same object
    f(c);
    // c still points to a but a is now 3.
    printf("*c = %d\n", *c);
    return 0;
}

The effect is the same in Python except that I can't use an int for
the demo since they're immutable:

b = [2]

def g(d):
    d[0] = 3 # Changes a which is also c and d
    d = b     # Doesn't affect a or c
    d[0] = 4 # Changes b

def main():
    a = [1]
    c = a   # a and c are the same object
    f(c)
    # c is still a but a is now [3]
    print("c =", c)

main()


Having taught beginners to program with C as a first programming
language and with Python as a first programming language I would say
that in either case this is an important fundamental concept that
beginners need to get their heads round. If a C programmer finds it
easier to understand how Python handles it by relating it to pointers
then that's great.


> 5) Furthermore, since a pointer is a value, you can have pointers to
> pointers, etc. Doesn't make any sense in Python.

You can have a reference to a container object which references other
objects. The effect is more or less the same if you want to understand
how something like this works:

a = [[0] * 5] * 5


--
Oscar



More information about the Python-list mailing list