SravanYegireddi
SravanYegireddi

Reputation: 3

Python, List append in recursion

rows = []

def rec(diry,level):
    if level == 2:
        diry['column_{}'.format(level)] = level
        rows.append(diry)
    else:
        diry['column_{}'.format(level)] = level
        rows.append(diry)
        rec(diry,level+1)

rec({},0)
print(rows)

The above code prints

[{'column_0': 0, 'column_1': 1, 'column_2': 2},
 {'column_0': 0, 'column_1': 1, 'column_2': 2},
 {'column_0': 0, 'column_1': 1, 'column_2': 2}]

Shouldn't it print

[{'column_0': 0},
 {'column_0': 0, 'column_1': 1},
 {'column_0': 0, 'column_1': 1, 'column_2': 2}]

Any suggestions will be helpful. Thanks

Upvotes: 0

Views: 82

Answers (4)

Dhaval Taunk
Dhaval Taunk

Reputation: 1672

You can change your code to this to get the desired output:-

rows = []

def rec(diry,level):
    if level == 2:
        diry['column_{}'.format(level)] = level
        # print(diry)
        rows.append(diry)
        print(diry)
    else:
        diry['column_{}'.format(level)] = level
        rows.append(diry)
        print(diry)
        rec(diry,level+1)

rec({},0)

Output:-

{'column_0': 0}
{'column_0': 0, 'column_1': 1}
{'column_0': 0, 'column_1': 1, 'column_2': 2}

Now you can compare this code and your code to get the intuition of why you are getting the result you were thinking.

Upvotes: 0

Sebastian
Sebastian

Reputation: 561

I am going from top to bottom but i think it is what you want:

def rec_append(n):
    if n == 0:
        return [{f'col{n}': n}]
    else:
        return (rec_append(n-1)) + [{f'col{n}': n for n in range(n+1)}]

print(rec_append(3))
[{'col0': 0},
 {'col0': 0, 'col1': 1},
 {'col0': 0, 'col1': 1, 'col2': 2},
 {'col0': 0, 'col1': 1, 'col2': 2, 'col3': 3}]

Upvotes: 1

Code Pope
Code Pope

Reputation: 5449

You are changing the dictionary in your iterations and inserting a reference to it in the list. At the end you have inserted three times the reference to the same dictionary and therefore the last print is just three printing outputs of the same dictionary.
If you really want to have each time a reference to the dictionary at that time you have to make a copy:

rows = []
import copy
def rec(diry,level):
    if level == 2:
        diry['column_{}'.format(level)] = level
        rows.append(diry)
    else:

        diry['column_{}'.format(level)] = level
        rows.append(copy.deepcopy(diry))
        rec(diry,level+1)

rec({},0)
print(rows)

Output:

[{'column_0': 0}, {'column_0': 0, 'column_1': 1}, {'column_0': 0, 'column_1': 1, 'column_2': 2}]

Upvotes: 0

Austin
Austin

Reputation: 26039

It is something distracting for beginners. You have to make sure that you pass a copy of dictionary or else it is the same reference to dictionary that you end up modifying:

rec(diry.copy(), level+1)

Code:

rows = []

def rec(diry,level):
    if level == 2:
        diry['column_{}'.format(level)] = level
        rows.append(diry)
    else:
        diry['column_{}'.format(level)] = level
        rows.append(diry)
        rec(diry.copy(),level+1)     # CHANGE HERE

rec({},0)
print(rows)

Upvotes: 1

Related Questions