1

I have a legit situation like this where I need to implement a method that changes the incoming object itself (convert list into dict)

def f(l): # f is a function that receives a list as input
    pass # Implement this


x = ['Hello', 'World']
f(x)
print(x) # x is now a dict {'hello':'world'}

How will you implement the above f() ?

The key thing is upon calling f() the incoming object itself must be mutated into different type.

Note: Genuine answers welcome instead of questioning the situation.

7
  • so you want to mutate something outside of the closure of the function? this screams of future bugs, in any case can't you just declare l to be global within your closure Commented Mar 24, 2019 at 23:59
  • 1
    Can you return the mutated object and assign returned object to x? I.e. x = f(x) Commented Mar 25, 2019 at 0:01
  • 1
    I don't understand the issue. Pass a mutable object to the function and return it. Commented Mar 25, 2019 at 0:01
  • 1
    The only way to get the exact behavior you are showing here is to mutate the global variable x. Without doing serious hacks, you cannot do this generically. Python does not support call by reference semantics. And certainly, transforming the type of the object itself will take serious hacking. Not something you want to do, unless you enjoy debugging arcane segfaults due to you messing with interpreter internals. Commented Mar 25, 2019 at 0:05
  • 2
    Also, given the fact that no major python code base requires the "need to implement a method that changes the incoming object itself (convert list into dict)", you are going to have to handle people questioning the situation. Because this screams X-Y problem Commented Mar 25, 2019 at 0:08

2 Answers 2

2

Python does not have a way to do what you want. You cannot change the binding of a variable in the calling context from within a function.

Of course, "cannot" has to be qualified: Python has many introspection capabilities, even letting you examine the calling stack, and the globals and locals in calling frames. But I strongly recommend against going that way.

I know you said you didn't want people to question the need for this, but I can't help thinking there is a better way to solve the problem.

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

3 Comments

Much appreciated Ned, introspection module which is the solution I'm after. The question itself is a watered down version of my actual scenario which you can trust me for being legit. And it doesn't take a python engineer to say something in the line of 'return and assign it to a new variable', which is silly.
I would be interested to see the actual situation.
BTW, if you truly mean that the same object must now have a different type (as opposed to just reassigning x to be a dict), then even introspection won't help you.
0

I dont think this is possible as you can modify a mutable when you pass it and have it reflect the changes in the global scope but you cannot change what it references.

def f(x):

    z = dict()
    for i in range(0,len(x),2):
        z[x[i]] = x[i+1]

    # x = z
    x.append(1)
    return x


x=[1,2]
z=f(x)
print(z) #[1, 2, 1]
print(x) #[1, 2, 1]

But

def f(x):

    z = dict()
    for i in range(0,len(x),2):
        z[x[i]] = x[i+1]

    x = z
    return x


x=[1,2]
z=f(x)
print(z) #{1: 2}
print(x) #[1, 2]

Python allows you to modify the global scope of mutable variables but you cannot change the reference itself.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.