4

what i want is to change all elements in a list with an unknown initial shape, so i made this helper function, but is there a better (shorter) way, or a builtin to do this?

and also another question on the side, where is the best place to store such a function >if< there is no builtin, instead of copy paste it in every file, or project

def getNextList():
    yield [1]
    yield [[1,2],3]
    yield [[1,2,[3]], [4,5],6]

def change(next_list, function):
    for i, e in enumerate(next_list):
        if(isinstance(e, int)):
            next_list[i] = function(next_list[i])
        else: change(e, function)

for next_list in getNextList():
    change(next_list, lambda x: x+1)
    print(next_list)

desired output:

 [2] 
 [[2, 3], 4] 
 [[2, 3, [4]], [5, 6], 7]

Edit: @Colin Schoen is is not a duplicate of your tagged question, because iterating twice would just give me an Error

i guess the solution i posted, or the version of @blhsing which is indeed shorter, is the only one for that particular problem, but if i stick to it, what would be the way to have that function available across different projects without duplicating it?

rpanai
  • 12,515
  • 2
  • 42
  • 64
Gotti92
  • 742
  • 1
  • 6
  • 22

1 Answers1

2

You can make change return a generator expression instead so that it can make use of the returning value of the recursive call:

def change(next_list, function):
    return (list(change(e, function)) if isinstance(e, list) else function(e) for e in next_list)

so that:

for changed_list in change(getNextList(), lambda x: x+1):
    print(changed_list)

outputs:

[2]
[[2, 3], 4]
[[2, 3, [4]], [5, 6], 7]

As for your second part of the question, you can store this function in a separate module, such as utils.py, inside a directory that is part of your PYTHONPATH environment variable, so that any project of yours can simply do from utils import change to make this function available in the namespace.

blhsing
  • 91,368
  • 6
  • 71
  • 106