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.

Nathaniel Jones
  • 939
  • 1
  • 14
  • 25
  • You could always just do `switcher[param] = final_val` – cs95 Mar 29 '18 at 00:21
  • 3
    Don't use a bunch of variables, use *a container, like a dictionary*. – juanpa.arrivillaga Mar 29 '18 at 00:22
  • Just use a dict. – Stephen Rauch Mar 29 '18 at 00:22
  • @COLDSPEED That does not modify the value of the variable, only the dictionary element. – Nathaniel Jones Mar 29 '18 at 00:29
  • 2
    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. – juanpa.arrivillaga Mar 29 '18 at 00:31
  • @juanpa.arrivillaga Ah, so instead of `return a, b`, I would end up with `return var_dict['a'], var_dict['b']`? – Nathaniel Jones Mar 29 '18 at 00:32
  • @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. – juanpa.arrivillaga Mar 29 '18 at 00:33
  • Possible duplicate of [Replacements for switch statement in Python?](https://stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python) – Skandix Mar 29 '18 at 08:14
  • @Skandix 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? – Nathaniel Jones Mar 29 '18 at 16:42
  • @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. – WestCoastProjects Feb 11 '20 at 01:21
  • @javadb, big miss? What language and structure do feel is so superior in this regard? – Stephen Rauch Feb 11 '20 at 01:38
  • look up `match/case` in _scala. Or any other language that supports assignment from arbitrary statements. – WestCoastProjects Feb 11 '20 at 01:41
  • https://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 itself – WestCoastProjects Feb 11 '20 at 01:47
  • 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. – Stephen Rauch Feb 11 '20 at 01:54
  • I think you missed the actual question which is trying to assign to "different" variables based on a question. – Stephen Rauch Feb 11 '20 at 01:55
  • [Python 3.10 (2021) has it](https://stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python/60211#60211). – Peter Mortensen Oct 05 '21 at 10:18

2 Answers2

4

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
Jimmy Lee Jones
  • 785
  • 4
  • 18
  • 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). – Nathaniel Jones Mar 29 '18 at 17:07
  • @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... – Jimmy Lee Jones Feb 12 '20 at 09:12
  • @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`. – WestCoastProjects Feb 12 '20 at 13:59
  • 1
    [Python 3.10 (2021) has it](https://stackoverflow.com/questions/60208/replacements-for-switch-statement-in-python/60211#60211). – Peter Mortensen Oct 05 '21 at 10:19
0

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
Nathaniel Jones
  • 939
  • 1
  • 14
  • 25