[Tutor] Two dimensional lists

Cameron Simpson cs at cskk.id.au
Mon Nov 2 03:53:39 EST 2020


On 02Nov2020 18:36, Phil <phillor9 at gmail.com> wrote:
>On 2/11/20 5:22 pm, Cameron Simpson wrote:
>I've explicitly laid out a list of lists.
>
>Thank you again Cameron.

You said you had some C++ code, so I'm going to provide some C code 
below to show some mechanism in a form I hope you're already familiar 
with.

>I left a pair of square brackets off my previous reply. It's been a 
>long day and this is what I meant in my reply:
>
>>>> b = [[5],[5]]

This implements a 2x1 list of lists and assigns a reference to it to 
"b".

>>>> b[3][2] = 9
>Traceback (most recent call last):
>  File "<stdin>", line 1, in <module>
>IndexError: list index out of range

Thus the index errors: you have a 2x1 data structure, not a 5x5 data 
structure.

>I know there's still a problem there, I'll look into it tomorrow.

I think you're still conflating declarations and assignments. In C one 
might write:

    int aa[5][5];

That _declares_ a 5x5 array of ints and implicitly fills it with zeroes.

In Python you don't declare variables. A variable is just a reference to 
an object (a list is an object, so is an int). They are not pointers, 
but if you think of them as pointers it will be useful for your mental 
model.

So, here's your b= _assignment_:

    b = [5], [5]

which is a 2-tuple if 1-lists. This is _similar_ to this piece of C:

    int l1[1] = { 5 };
    int l2[1] = { 5 };
    int *b[2] = { l1, l2 };

It is not a perfect metaphor, because lists are resizeable, so a closer 
analogy might be this:

    int *l1 = malloc(1 * sizeof(int));
    l1[0] = 5;
    int *l2 = malloc(1 * sizeof(int));
    l2[0] = 5;
    int *b[2] = { l1, l2 };

So malloc() a resizable piece of memory holding 1 int and keep a pointer 
to it in l1. Repeat for l2. Then allocate a fixed size 2-element array 
of int* to point at l1 and l2.

Now, that is for:

    b = [5], [5]

which is equivalent to:

    b = ( [5], [5] )

i.e. that makes "b" refer to a 2-tuple. With your missing square 
brackets:

    b = [ [5], [5] ]

you're making a 2-list instead of a 2-tuple: the real different is that 
a list can be mmodified. So this is like this C code:

    int *l1 = malloc(1 * sizeof(int));
    l1[0] = 5;
    int *l2 = malloc(1 * sizeof(int));
    l2[0] = 5;
    int **b = malloc(2 * sizeof(int*));
    b[0] = l1;
    b[1] = l2;

So "b" now points at a resizable piece of memory holding 2 pointers 
instead of a fixed size piece of memory.

Cheers,
Cameron Simpson <cs at cskk.id.au>


More information about the Tutor mailing list