Multi-dimensional list initialization

Andrew Robinson andrew3 at
Thu Nov 8 00:55:30 CET 2012

On 11/07/2012 05:39 AM, Joshua Landau wrote:
> On 7 November 2012 11:11, Oscar Benjamin wrote:
>     On Nov 7, 2012 5:41 AM, "Gregory Ewing"  wrote:
>     >
>     > If anything is to be done in this area, it would be better
>     > as an extension of list comprehensions, e.g.
>     >
>     >   [[None times 5] times 10]
>     >
>     > which would be equivalent to
>     >
>     >   [[None for _i in xrange(5)] for _j in xrange(10)]
Oscar, I'm really in agreement with you;  I think that it's better to 
group all *special* array/list constructions into a single logical unit 
which will show up in the same part of the Python documentation.
>     A multidimensional list comprehension would be useful even for
>     people who are using numpy as it's common to use a list
>     comprehension to initialise a numpy array.
I hadn't paid that much attention; but I think that's true of people 
using the newer releases of Numpy.
A Very interesting point... Thank you for mentioning it.

>     A more modest addition for the limited case described in this
>     thread could be to use exponentiation:
>     >>> [0] ** (2, 3)
>     [[0, 0, 0], [0, 0, 0]]
I'm against over using the math operators, for the reason that matrix 
and vector algebra have meanings mathematicians desire (rightly) to 
maintain.  Numpy users might find matricies overloaded to do these 
things in the future -- and then it becomes unclear whether an 
initialization is happening or a mathematical operation. I think it best 
just not to set up an accident waiting to happen in the first place.

> Hold on: why not just use multiplication?
> >>> [0] * (2, 3)
Would you consider that better than [0].nest(2).nest(3) ? or [0].nest(2,3) ?
(I'm against multiplication, but I'm still interested in what you find 
attractive about it.)
> We do have to think of the potential problems, though. There are 
> definitely some. For one, code that relies on lst * x throwing an 
> error would break. It may confuse others - although I don't see how.
Excellent observation:
People relying on an exception, would be in the try: operation.
So, since lst * int  does not cause an exception; they would need a 
reason to be concerned that someone passed in a list instead of an 
integer.  Semantically, the same KIND of result happens, lst is in some 
way duplicated; so if the result is accepted, it likely would work in 
place of an integer.
So, the concern would be where someone wanted to detect the difference 
between an integer and a list, so as to run some alternate algorithm.

Eg, say a vector multiply, or similar operation.  The design would want 
to shadow * and call a method to do the multiply; You'd have a fragment 
possibly like the following:

     try: ret = map( lambda x: x*rightSide, leftSide )
     except TypeError:  for i in rightSide: self.__mul__( rightSide, i ) 
# recursive call to __mul__

That's a common technique for type checking dating from earlier releases 
of Python, where the "type" attribute wasn't available.  It also works 
based on functionality, not specific type -- so objects which "work" 
alike (subclasses, alternate reinventions of the wheel) also can be handled.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the Python-list mailing list