List replication operator

Steven D'Aprano steve+comp.lang.python at pearwood.info
Thu May 24 22:30:30 EDT 2018


On Thu, 24 May 2018 16:05:32 -0700, Paul wrote:

> How would one make a multi-dimensional list now, with truly-separate sub
> lists?  Is there just no way to do it with the replication operator?

Correct. Let's say you want to make a 1-D list with three items 
initialised to zero. This works brilliantly:

py> [0]*3
[0, 0, 0]

This seems like it ought to create a 3x3 2-D list:

py> y = [[0]*3]*3
py> y
[[0, 0, 0], [0, 0, 0], [0, 0, 0]]


but alas, it's a trap:

py> y[0][0] = 1
py> y
[[1, 0, 0], [1, 0, 0], [1, 0, 0]]


The current recommended solution is:

py> y = [[0]*3 for _ in range(3)]
py> y[0][0] = 1
py> y
[[1, 0, 0], [0, 0, 0], [0, 0, 0]]


To get a three-dimensional 3x3x3 list is even more work:

py> z = [[[0]*3 for _ in range(3)] for _ in range(3)]
py> z[0][0][0] = 1
py> z[1][1][1] = 2
py> z[2][2][2] = 3
py> z
[[[1, 0, 0], [0, 0, 0], [0, 0, 0]], 
 [[0, 0, 0], [0, 2, 0], [0, 0, 0]],
 [[0, 0, 0], [0, 0, 0], [0, 0, 3]]]



With my suggestion, we get:

x = [0]**3  # one-dimensional
y = [[0]**3]**3  # two-dimensional
z = [[[0]**3]**3]**3  # three-dimensional

Or there's MRAB's suggestion of using @ instead.

The one-dimensional case can be optimized by using regular * replication 
instead of ** duplication, but that's an optimization for immutable 
objects.


Here's a subclass that implements a simple version of this for testing:

class ML(list):
    def __pow__(self, other):
        import copy
        L = []
        for i in range(other):
            L.extend(copy.deepcopy(obj) for obj in self)
        return ML(L)


And in use to generate a 3-D list:

py> z = ML([ML([ML([0])**3])**3])**3
py> z[0][0][0] = 1
py> z[1][1][1] = 2
py> z[2][2][2] = 3
py> z
[[[1, 0, 0], [0, 0, 0], [0, 0, 0]],
 [[0, 0, 0], [0, 2, 0], [0, 0, 0]],
 [[0, 0, 0], [0, 0, 0], [0, 0, 3]]]


The repeated calls to ML() are ugly and are only there because the [] 
syntax creates ordinary lists, not my subclass.


-- 
Steve




More information about the Python-list mailing list