[Tutor] Two dimensional lists

Cameron Simpson cs at cskk.id.au
Sun Nov 1 23:46:41 EST 2020


On 02Nov2020 11:24, Phil <phillor9 at gmail.com> wrote:
>I have some C++ code that I wrote some time ago and, just as an 
>exercise, I'm converting it to Python. I've come to a standstill 
>because of arrays. If I use a numpy array as follows then I can use 
>that array in exactly the same way as a C++ array even though I don't 
>understand the syntax of it. I used the trial_and_error method to 
>create it.

This can be deceptive. Read the documentation. (Disclaimer: I know 
nothing about numpy.)

>Python lists, if I understand this correctly, can be used in the same 
>way as arrays.

Linear arrays yes. Anything else you need to build.

>However, I've made little progress. Is there a list equivalent to this?
>
>b = [5] , [5] # a square array of size 5
>
>b[3][2] = 9

For the syntax you show above, the direct Python equivalent is a 5 
element list, each element of which is a 5 element list.

So:

    b = [
          [ 0, 0, 0, 0, 0 ],
          [ 0, 0, 0, 0, 0 ],
          [ 0, 0, 0, 0, 0 ],
          [ 0, 0, 0, 0, 0 ],
          [ 0, 0, 0, 0, 0 ],
        ]

The syntax you use "b[3][2]" fetches element 3 (the fourth element, 
since lists count from 0), and then fetches element 2 from _that_. So 
the third element of the fourth list.

Depending on you needs, something basic like that will do. For large 
arrays you want something sparse (not a fully filled out list of lists) 
or something fast (maybe a single flat list, eg 25 elements in the 
example above, and an indexing approach to turn a pair of coordinates 
into the right flat index).

Finally, since you're fond of syntactic experiment, note that Python has 
a convenient replication syntax. It does not do what you would first 
expect:

You can make a 5 element list like this:

     l5 = [0] * 5

but note that is a 5 element list, each of whose elements is the _same_ 
object (an int of value 0 in this case). For ints that's fine, the small 
ones are immutable singletons anyway - changes involve making new ints.  

But you might be tempted to do this:

     l5 = [0] * 5
     l55 = l5 * 5

like this:

    >>> l5
    [0, 0, 0, 0, 0]
    >>> l55 = l5 * 5
    >>> l55
    [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Whoops. Better do that correctly:

    >>> l55 = [l5] * 5
    >>> l55
    [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

That looks like our first example, but it is not. Watch:

    >>> l55[3][2] = 7
    >>> l55
    [[0, 0, 7, 0, 0], [0, 0, 7, 0, 0], [0, 0, 7, 0, 0], [0, 0, 7, 0, 0], [0, 0, 7, 0, 0]]

Why? Because l55 is a list of 5 elements, each of which is a reference 
to the _same_ 5 element list we made as "l5":

    >>> l5
    [0, 0, 7, 0, 0]

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


More information about the Tutor mailing list