1

I apologise if the question is indirect or confusing. What I'm trying to achieve is a list like the one below:

[[[0,0],[0,0],[0,0]],[[0,0],[0,0],[0,0]],[[0,0],[0,0],[0,0]]]

However, I want the list to have a variable amount of list "depth" (the above list has a list "depth" of 3 since it a maximum of 3 lists at the bottom; to access an item in it it would look like `aList[1][0][1]` )

I have tried using list comprehension:

aList = [[[[None for _ in range(3)] for _ in range(3)] for _ in range(3)] for _ in range(3)]

The only problem with this is that I can't change the depth of the list without directly editing the code.

What can I do to achieve the result I'm after? (The list I am trying to achieve contains 7^4 (2401) items, just so you're aware.)

5
  • The list comprehension will become incomprehensible pretty quickly. It sounds like a good job for a recursive function .. Commented Feb 10, 2023 at 20:14
  • Shall the lists have the same size or different sizes? Commented Feb 10, 2023 at 20:38
  • @KellyBundy different sizes. the width and depth of the lists have to be variable. Commented Feb 11, 2023 at 13:05
  • Hmm, that's unclear. What are the width and depth of the lists in your first example? (The [[[0,0], ... one). Commented Feb 11, 2023 at 13:10
  • @KellyBundy a depth of 3, and the widths are different for each level. 3 for the first, 3 for the next, and 2 for the last. Commented Feb 11, 2023 at 13:12

6 Answers 6

3

This might be a nice job for :

import numpy as np

out = np.zeros((3, 3, 2), dtype=int).tolist()

Output:

[[[0, 0], [0, 0], [0, 0]],
 [[0, 0], [0, 0], [0, 0]], 
 [[0, 0], [0, 0], [0, 0]]]

Or with a recursive function:

def nested(shape):
    if shape:
        n, *shape = shape
        return [nested(shape) for _ in range(n)]
    return 0

out = nested((3, 3, 2))
Sign up to request clarification or add additional context in comments.

2 Comments

just to confirm, i can pass in (3, 3, 2) as a tuple?
@iCxbe yes shape should be a tuple (or iterable)
2

Recursion is your friend:

def nested_list(depth, size):
    if depth == 1:
        return [None for _ in range(size)]
    return [nested_list(depth-1, size) for _ in range(size)]

1 Comment

Can't produce their first example, as their sizes aren't all the same.
0

Pure python solution

My recommendation: only if you can't use numpy.

Recursion

Warning, this code is simple but have a depth limit depending on your configuration.

from pprint import pprint


def list_in_depth_recursive(depth: int, length: int | None = None):
    """limited by stack size (default 500 or 1000)"""
    if length is None:
        length = depth

    if depth <= 1:
        return [None] * length

    return [list_in_depth_recursive(depth - 1, length) for _ in range(length)]


pprint(list_in_depth_recursive(3))
# [[[None, None, None], [None, None, None], [None, None, None]],
#  [[None, None, None], [None, None, None], [None, None, None]],
#  [[None, None, None], [None, None, None], [None, None, None]]]
>>> pprint(list_in_depth_recursive(10000))
RecursionError: maximum recursion depth exceeded in comparison

Iterative

Warning, because of the deepcopy, you can also produce a RecursionError with this code.

from copy import deepcopy
from pprint import pprint


def list_in_dept_iterative(depth: int, length: int | None = None):
    """limited by memory"""
    if length is None:
        length = depth

    if depth <= 0:
        return [None]

    current_depth_list = [None] * length
    while depth > 1:
        current_depth_list = [deepcopy(current_depth_list) for _ in range(length)]
        depth -= 1
    return current_depth_list


pprint(list_in_dept_iterative(3))
# [[[None, None, None], [None, None, None], [None, None, None]],
#  [[None, None, None], [None, None, None], [None, None, None]],
#  [[None, None, None], [None, None, None], [None, None, None]]]

4 Comments

the list im after is actually pretty big (7^4 = 2401) so im not sure if recursion would be acceptable. thank you though.
@iCxbe Hmm? Do you mean 7×7×7×7 like your first example is 3×3×2? Then that's not "pretty big" but really small, and none of the solutions would have the slightest problem with it. Do you mean something else?
list_in_depth_recursive(4, 7) is not an issue. It is if you need a depth of 500 or 1000+ only. list_in_depth_recursive(1000) is usually the limit, so a much bigger list, 1000^1000.
@DorianTurba oh alright, that was just a case of me not understanding the issue. thanks for clarification.
0

A recursive approach with reduce

from functools import reduce

shape = 3, 2, 5
lst = reduce(lambda row, dim: row + [[0] * dim], shape, [])
#[[0, 0, 0], [0, 0], [0, 0, 0, 0, 0]]

Comments

0

Recursion is probably your best bet for this:

def matrix(size,*more):
    return [matrix(*more) for _ in range(size)] if more else [0]*size

output:

matrix(3,3,2)

[[[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0]]]

You could also do it iteratively by splitting an initial 1D list to break it down for each dimension:

def matrix(*dims):
    result = [0]
    for d in dims: result *= d
    for d in dims[:0:-1]:
        result = [ result[i:i+d] for i in range(0,len(result),d) ]
    return result

Comments

-2

We can multiply if we deduplicate via string:

a = eval(str([[[0]*2]*3]*3))

For variable sizes like sizes = 2, 3, 3:

n = len(sizes)
a = eval(str(eval('[' * n + '0' + ']*%d' * n % sizes)))

Try it online!

4 Comments

i think the issue with this is that the values all point to the same areas, so when i would try to change a single value, multiple values would change at once, and that's not what im after.
@iCxbe That's not true. The deduplication fixes that. It's also hard to overlook the deduplication code, and I explicitly pointed it out in the text.
still, theres another issue. what if i want the depth to change through the change of a single variable? this has a fixed depth, and it wouldn't be easy to change it without directly editing the code itself. provide a solution to this if possible, given that i did specify that the depth has to be variable.
@iCxbe Ah yes, that is a real issue. I actually started with a variable version and then apparently forgot about that. It was late last night. I'll add a variable one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.