2

I have a function f(x) in which many local variables are created. x is a string with the same name as one of these local variables and I would like to change this local variable by changing x. What is the clean way to do this? Currently I am using a lot of if/elif statements.

Some dummy code to represent my problem:

def f(x):
         a = [1,2,3]
         b = [2,3,4]
         c = [3,4,5]
         if x == "a":
                     a[0] = 10
         elif x == "b":
                     b[0] = 10
         elif x == "c":
                     c[0] = 10
         return a,b,c

I would like for the right variable to change value but using all these if/elif statements feels a bit redundant.

HolyMonk
  • 432
  • 6
  • 17

4 Answers4

5

Use a dict

Simply, use a dict:

def f(x):
    values = {
        "a": [1,2,3],
        "b": [2,3,4],
        "c": [3,4,5]
    }
    values[x][0] = 10
    return values["a"], values["b"], values["c"]

If you really really want, use your original code and do locals()[x][0] = 10 but that's not really recommended because you could cause unwanted issues if the argument is the name of some other variable you don't want changed.

hyper-neutrino
  • 5,272
  • 2
  • 29
  • 50
4

use dictionary like this:

def f(x):
     d = {"a" :[1,2,3],"b" : [2,3,4],"c" : [3,4,5]}
     d[x][0] = 10

     return d
ddor254
  • 1,570
  • 1
  • 12
  • 28
1

If your input is a string and you want to refer to a variable that matches that string you can use globals() like this:

globals()['x']

This way you can get the value and/or edit its contents.

zipa
  • 27,316
  • 6
  • 40
  • 58
  • 4
    Ok, so, 1) using `globals()` is a bad idea 99.999% of the time, and 2) you don't know whether x is a name at the global scope anyway. what if `x` is first created inside a `main` function, which then calls `f`? globals() won't have an 'x' entry in that case. – Kevin Sep 26 '17 at 14:46
  • How else is he going to access the variable, except maybe using `locals()`? Sure he can rewrite the code, but this answer is for this specific situation. – zipa Sep 26 '17 at 14:48
  • 1
    This is a classic X-Y problem, you answer their question too literally, use a `dict` instead – Chris_Rands Sep 26 '17 at 14:51
  • I guess it's a moot point now, since OP's edited post clarifies that it really doesn't have anything to do with differently scoped variables. – Kevin Sep 26 '17 at 14:51
-2

You can use exec() and put your code in argument as a string

def f(x):
    a = [1,2,3]
    b = [2,3,4]
    c = [3,4,5]
    exec(x + "[0] = 10")

    return a,b,c

print f("a")
# ([10, 2, 3], [2, 3, 4], [3, 4, 5])
B 7
  • 670
  • 7
  • 23
  • 2
    Sure you _can_, but you _shouldn't_. `exec` is both a security hazard and a performance hog. See for example https://stackoverflow.com/questions/2220699/whats-the-difference-between-eval-exec-and-compile-in-python?rq=1 – Guillaume Sep 26 '17 at 14:54