populating a doubly-subscripted array

Ben Finney ben+python at benfinney.id.au
Tue Nov 9 00:27:50 CET 2010


ghw at accutrol.com writes:

> What am I missing?

You're missing the fact that Python doesn't have a built-in “array”
type, nor really “subscripts” for them.

> ff = [[0.0]*5]*5

This creates a float object, ‘0.0’. It then creates a list containing
five references to that same object. It then creates a new list
containing five references to the first list. It then binds the name
‘ff’ to the outer list.

    ff --+
         |
         V

    +---+---+---+---+---+
    | . | . | . | . | . |
    +-|-+-|-+-|-+-|-+-|-+
      |   |   |   |   |
      +---+---+---+---+---+
                          |
                          V

                +---+---+---+---+---+
                | . | . | . | . | . |
                +-|-+-|-+-|-+-|-+-|-+
                  |   |   |   |   |
                  +---+---+---+---+---+
                                      |
                                      V

                                      0.0

> ff                        #(lists 5x5 array of 0.0)

Nope. It outputs the structure described above, serialised. There is no
distinction in that output between objects that are different but have
the same value, versus the same object displayed several times. Try the
‘is’ (identity) and ‘==’ (equality) operators to see the difference.

> for i in range(5):
>   for j in range(3):
>     ff[i][j] = i*10+j

This binds different integer values at some of the references in the
inner list. As the loops continue, the reference used to get at the
inner list is different; but it's always the same list.

>     print (i,j,ff[i][j])  # correctly prints ff array values

It prints the values in the inner list immediately after they're
assigned. As the loops continue, the references are re-bound to other
integer values.

> ff                        # try this and see what happens!

After all the changes, the only references which have actually been
re-bound are the first three items in the inner list.

    ff --+
         |
         V

    +---+---+---+---+---+
    | . | . | . | . | . |
    +-|-+-|-+-|-+-|-+-|-+
      |   |   |   |   |
      +---+---+---+---+---+
                          |
                          V

                +---+---+---+---+---+
                | . | . | . | . | . |
                +-|-+-|-+-|-+-|-+-|-+
                  |   |   |   |   |
                  |   |   |   +---+---+
                  |   |   |           |
                  V   V   V           V

                  40  41  42          0.0

> result of third print of ff
> [[40, 41, 42, 0.0, 0.0], [40, 41, 42, 0.0, 0.0], 
> [40, 41, 42, 0.0, 0.0], [40, 41, 42, 0.0, 0.0], 
> [40, 41, 42, 0.0, 0.0]]
>
> Obviously there is something missing in my understanding of how array
> values are populated. Why do all "rows" get populated with the same
> set of values (40, 41, 42)?

Because, as the above diagram hopefully clarifies, a list isn't an
array, and its references aren't rows.

If you actually want an array, there isn't a built-in type for it.
Instead, use the standard library ‘array’ module
<URL:http://docs.python.org/library/array.html>, or (for more powerful
numeric processing) the types in the third-party NumPy library
<URL:http://numpy.scipy.org/>.

-- 
 \        “When you go in for a job interview, I think a good thing to |
  `\                  ask is if they ever press charges.” —Jack Handey |
_o__)                                                                  |
Ben Finney



More information about the Python-list mailing list