Shrinking very large If statements in python

Viewed 55

I have a situation where I have 4 variables named eax,ebx,ecx and edx, and any one of them may be set to any of these vars: var1,var,var3 and var4, however they are set as the string "varx" instead of the value of varx, but only one of them will every need fixing at a time. I have been using this if statement:

  if eax=="var1":
    eax=var1
  elif ebx=="var1":
    ebx=var1
  elif ecx=="var1":
    ecx=var1
  elif edx=="var1":
    edx=var1
  elif eax=="var2":
    eax=var2
  elif ebx=="var2":
    ebx=var2
  elif ecx=="var2":
    ecx=var2
  elif edx=="var2":
    edx=var2
  elif eax=="var3":
    eax=var3
  elif ebx=="var3":
    ebx=var3
  elif ecx=="var3":
    ecx=var3
  elif edx=="var3":
    edx=var3
  elif eax=="var4":
    eax=var4
  elif ebx=="var4":
    ebx=var4
  elif ecx=="var4":
    ecx=var4
  elif edx=="var4":
    edx=var4

But I am aware that this is very bad practise. Is there a way for me to compact this if statement?

Thanks.

3 Answers

You could try thinking about the update process for a single variable at a time and create a function to handle that. Then the logic can be easily reused for each variable. This means you'll have a function that handles 4 (or 5) cases and call it 4 times (resulting in 8-9 steps) instead of having to do each combination (16 steps). This also has the benefit of making your code more readable and maintainable.

For example:

def get_var(x):
    if x == "var1":
        return var1
    if x == "var2":
        return var2
    if x == "var3":
        return var3
    if x == "var4":
        return var4
    return x

eax = get_var(eax)
ebx = get_var(ebx)
ecx = get_var(ecx)
edx = get_var(edx)

Note this is basically a switch statement (which is not supported by Python), and can instead be written in the following way (which can be easier to update depending on the rest of your code):

vars_lookup = {
    "var1": var1,
    "var2": var2,
    "var3": var3,
    "var4": var4,
}

def get_var(x):
    return vars_lookup.get(x, x)

eax = get_var(eax)
ebx = get_var(ebx)
ecx = get_var(ecx)
edx = get_var(edx)

Note here that the get method of the dict type works like the usual brackets notation (vars_lookup[x]), but handles cases where the key is not found in the dictionary and then returns the default value (the second argument).

You may use vars()

variable_list = [v for v in [eax, ebx, ecx, edx] if v is not str else vars()[v]]

or

eax = vars()[eax] if eax is not str else eax
ebx = vars()[ebx] if ebx is not str else ebx
ecx = vars()[ecx] if ecx is not str else ecx
edx = vars()[edx] if edx is not str else edx

This is only a more "hacky" version, the answer from @Henry Woody is more readable while this being cleaner. I would recommend his over this for the sake of being more pythonic

By far the easiest solution is to use a dictionary. Simply define it like this:

var_dict = {
    'var1':var1,
    'var2':var2,
    'var3':var3,
    'var4':var4,
    }

Then when you find a situation where you need to translate from the string value to the variable, do this:

eax = "var1" #as an example
eax = var_dict[eax] #now eax is the variable var1

This will change eax, in this case, from "var1" to the actual variable itself, var1. You could even store functions in your dictionary this way if you so desired. You would simply call them with:

var_dict[eax]()
Related