'switch'/'case' for determining the variable to assign to in Python
Asked Answered
W

2

5

I'd like to use a "switch/case" structure to decide which variable to assign a value to based on some parameter:

a, b = [init_val] * 2
# This doesn't exist in Python.
switch param
    case 'a':
        a = final_val
    case 'b':
        b = final_val

The dictionary method described in the question Replacements for switch statement in Python doesn't work here, since you can neither assign to a function call,

a, b = [init_val] * 2
switcher = {
    'a': a,
    'b': b
}
switcher.get(param) = final_val

nor change the value of a variable by storing it in a dictionary:

switcher[param] = final_val  # switcher['a'] is only a copy of variable a

I could just stick to "if/elif", but since I have often seen that nice dictionary solution (as in the aforementioned question) for determining an output based on some parameter, I'm curious to see if there's a similar solution for determining which variable, out of a set of variables, to assign a value to.

Wertheimer answered 29/3, 2018 at 0:19 Comment(16)
You could always just do switcher[param] = final_valBasilicata
Don't use a bunch of variables, use a container, like a dictionary.Junto
Just use a dict.Vicarial
@COLDSPEED That does not modify the value of the variable, only the dictionary element.Wertheimer
Anyway, you can dynamically assign to a global variable rather easily in Python: globals()[switcher.get(param)] = final_val, however, this is hackey, and really suggests that your "variables" should just be keys in their own dictionary, instead of clobbering the globals dictionary. Dynamically assigning to local variables is tougher in Python, and will be version / implementation dependent. Python 3 has made this a lot harder. Just don't do it. I hesitate to say "never", but I've never seen a good reason to.Junto
@Junto Ah, so instead of return a, b, I would end up with return var_dict['a'], var_dict['b']?Wertheimer
@NathanielJones sure. Although, unless you have a bunch of variables, a simple if-else is probably fine in this case. No need to go around over-engineering things. Code is written once, but read many times.Junto
Possible duplicate of Replacements for switch statement in Python?Bezanson
@Bezanson I have just edited my question. I think it's slightly different than the one you mention. However, I am new to StackOverflow: Would this have worked better as a comment on that question?Wertheimer
@StephenRauch A dict requires a single value lookup: it misses out on conditional expressions for selection of the appropriate assignment. Just a big miss in python.Scuta
@javadb, big miss? What language and structure do feel is so superior in this regard?Vicarial
look up match/case in _scala. Or any other language that supports assignment from arbitrary statements.Scuta
docs.scala-lang.org/tour/pattern-matching.html But you can assign anything to a variable in scala: the point is that arbitrary statements or generators including conditional ones can produce a result that is assigned to a variable. I keep coming back to this and _hoping_/wishing python had something a little less awkward then explicitly assigning the output variable for every conditional branch. It also means setting the variable to None in a separate (/awkward) line by itselfScuta
Well I will have to respectable disagree that scala's match/case is somehow a so much better solution to the listed question that somehow this is a "big miss" in Python. Cheers.Vicarial
I think you missed the actual question which is trying to assign to "different" variables based on a question.Vicarial
Python 3.10 (2021) has it.Cornetist
C
5

Python, in general, does not have a built-in switch/case functionality. Instead, common practice is to use the elif keyword as such:

a, b = [init_val] * 2
if param == 'a':
    a = final_val
elif param == 'b':
    b = final_val
else:
    pass # or do something else
Crammer answered 29/3, 2018 at 6:45 Comment(4)
I was hoping to avoid the repetitive elif param == , but so far this seems like the way to go, and not much different from a switch/case (in fact, it involves less indentation).Wertheimer
@javadba Python has many advantages and many disadvantages, so does any other programming language. Claiming it is weak due to a single (lack of) feature is not very professional...Crammer
@JimmyLeeJones I can go into much more serious issues with python : this is a relatively smaller one . My preference would be to hear: "oh you can get around it this way or that way". Then i'd remove the comment. I do use the language: there is no numpy or tensorflow or opencv in scala or ruby.Scuta
Python 3.10 (2021) has it.Cornetist
W
1

Using Python 3.10 (2021), you can avail the match-case construct.

a, b = [init_val] * 2

# This exists in Python 3.10+
match param:
    case 'a':
        a = final_val
    case 'b':
        b = final_val
Wertheimer answered 14/7, 2023 at 20:40 Comment(1)
it's still not what we want (and have in scala and other more functional languages) but that's all we get.Scuta

© 2022 - 2024 — McMap. All rights reserved.