6

I need to write a function that receives an non-negative integer and returns:

[] for n=0 

[[]] for n=1 

[[],[[]]] for n=2

[[],[[]],[[],[[]]]] for n=3

And so on. For n, we will receive an n sized list, so that in index i there will be all the i-1 elements from the list. I don't know how to explain that better, English isn't my first language.

I'm not allowed to use list slicing or loops and I'm supposed to create deep copies of each list, without the copy module. I'm not allowed to let 2 different lists or indexes point to the same list in memory.

This is what I tried:

def list_seq(x, outer_list=[]):
    if x == 0:
        return []
    outer_list.append(list_seq(x-1,outer_list))
    return outer_list

And the output for print(list_seq(2)) is [[], [...]].

5
  • "I'm suppose to create deep copies of each list" Does that mean you are not supposed to cache the results of recursive calls? In this case, the will have very high complexity. Commented Nov 27, 2021 at 14:39
  • @tobias_k I'm not allowed that 2 different lists or indexes will point on the same list in memory Commented Nov 27, 2021 at 14:41
  • what did you try? Commented Nov 27, 2021 at 14:41
  • Do you consider the solution of your problem, created in C++? Commented Nov 27, 2021 at 14:52
  • 1
    @MadaBit why did you roll back your code attempt? The question would be off-topic without it. Commented Nov 27, 2021 at 15:25

4 Answers 4

4

If you can't use loops, you can use the following:

def recursive_list(n):
    if n == 0:
        return []
    else:
        return recursive_list(n-1) +  [recursive_list(n-1)]

EDIT

You can do the following if you want to use append:

def recursive_list(n: int) -> list:
    if n:
        result = recursive_list(n-1)
        result.append(recursive_list(n-1))
        return result
    return []

NOTE as pointed out in the comments, caching introduces some reference issues, so I have removed the cached versions.

Sign up to request clarification or add additional context in comments.

4 Comments

That's a great solution. Thank you very much. Is it possible with append method instead of +? Maybe with an helper function
Added a solution with append.
Using functools.cache defeats the whole purpose of making two recursive calls instead of one. Consider: l = recursive_list(4); print(l); [[], [[]], [[], [[]]], [[], [[]], [[], [[]]]]]; l[1].append('oops'); print(l); [[], [[], 'oops'], [[], [[], 'oops']], [[], [[], 'oops'], [[], [[], 'oops']]]]
@Stef fair. I just made sure the lists are not self-contained. I did not consider whether OP planned to append to the lists in-between, which is my oversight. Considering OP can't use slicing, or copy, or loops, not sure if the results can be cached at all. Even with some custom cache function, there needs to be some mechanism to copy the lists.
4

You can write this down as a recursive function using a simple list comprehension:

def f(n):
    return [f(i) for i in range(n)]

Or instead of the list comprehension, you could also use map:

def f(n):
    return list(map(f, range(n)))

Note, though, that without caching this is going to get rather slow rather quickly.

2 Comments

Sorry. Forgot to mention that i can't use loops
@MadaBit return [*map(f, range(n))] then?
1

An alternative shorter recursive solution, no loops:

def l_list(n):
  def f(c, d = []):
     return d if c == n else f(c+1, d+[l_list(c)])
  return f(0)

print(l_list(0))
print(l_list(1))
print(l_list(2))
print(l_list(3))

Output:

[]
[[]]
[[], [[]]]
[[], [[]], [[], [[]]]]

Comments

1

Just another idea, I think it fulfills all rules/requirements:

def f(n):
    a = []
    exec('a.append(1 * a);' * n)
    return eval(repr(a))

Demo usage:

for n in range(5):
    print(f(n))

Output:

[]
[[]]
[[], [[]]]
[[], [[]], [[], [[]]]]
[[], [[]], [[], [[]]], [[], [[]], [[], [[]]]]]

4 Comments

Neat idea, but scary implementation. Why not just for _ in range(n): a.append(list(a)) and then return a?
@tobias_k Because of the question's "I'm not allowed to use list slicing or loops".
@tobias_k And also because of its "I'm not allowed to let 2 different lists or indexes point to the same list in memory".
@tobias_k It doesn't

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.