1

Assume that the command line option will positively be the name of a dictionary in a Python 3 script. Is there a more pythonic way of replacing all the facacta if-elsif lines in the script with something really cool?

The command:

$ prog.py a

The script:

#!/usr/bin/evn python3

a = {'x' : '1', 'y' : '2'}
b = {'x' : '3', 'y' : '4'}
# and so on ..
nth = {'x' : '1000', 'y' : '2000'}
# and on ..

if __name__ == "__main__":
    z = dict()

    # There has got to be a better way
    if sys.argv[1] == 'a':
       z.copy(a)
    elif sys.argv[1] == 'b':
       z.copy(b)
    # and so on  ...
    elif sys.argv[1] == 'nth':
       z.copy(nth)
    # and on  ...
khelwood
  • 55,782
  • 14
  • 81
  • 108
user2569618
  • 517
  • 3
  • 16
  • 42
  • Does this answer your question? [How do I create a variable number of variables?](https://stackoverflow.com/questions/1373164/how-do-i-create-a-variable-number-of-variables) **Edit**: On second thought, the solution's the same but it's the reverse problem. They want to *create* variables dynamically, you want to *dereference* them dynamically. – wjandrea Dec 16 '19 at 23:07

3 Answers3

4

What about putting all those dictionaries together?

#!/usr/bin/env python3

d = {
    'a': {'x' : '1', 'y' : '2'},
    'b': {'x' : '3', 'y' : '4'},
     ...
     'nth': {'x' : '1000', 'y' : '2000'},
}

if __name__ == "__main__":
    z = dict()
    key = sys.argv[1]
    if key in d:
        z.update(d[key])
Mikel F
  • 3,567
  • 1
  • 21
  • 33
user48678
  • 2,382
  • 3
  • 24
  • 30
1

You could solve this with exec (but you probably shouldn't):

if __name__ == "__main__":
    z = dict()
    exec("z.update(" + sys.argv[1] + ")")

This will do what you want, with the massive downside of executing arbitrary user input, which is very unsafe. A safer solution is to store all the variables in a dictionary, although this could require other refactoring elsewhere:

d = {
    'a': {'x' : '1', 'y' : '2'},
    'b': {'x' : '3', 'y' : '4'},
     ...
     'nth': {'x' : '1000', 'y' : '2000'}
}

if __name__ == "__main__":
    z = dict()
    z.update(d[sys.argv[1]])
Mikel F
  • 3,567
  • 1
  • 21
  • 33
The Zach Man
  • 738
  • 5
  • 15
0
z = locals()[sys.argv[1]].copy()

Note that you will want to wrap this in a try/except statement in the case where the command line argument does not match a local variable.

If you are not looking to made a shallow copy:

z.update(locals()[sys.argv[1]])

Note that your use of copy in your sample code is not correct.

Mikel F
  • 3,567
  • 1
  • 21
  • 33