0

Suppose I have some variables:

a, b, c, d, e = range(5)

I want to save the values of these variables in a file for later inspection. One way I thought to do this was:

lookup = {
    'a': a,
    'b': b,
    'c': c,
    'd': d,
    'e': e
}

As you might imagine, with a large number of variables, this could get tedious. And, yes, I know many editors have functionality to make this kind of copy-paste action easy. But I'm looking for the standard, "Pythonic" way of dynamically building a key: value lookup where the key is the variable's name and the value is the variable's, well, value!

I thought about this:

>>> {var.__name__: var for var in [a, b, c, d, e]}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <dictcomp>
AttributeError: 'int' object has no attribute '__name__'

I'm not surprised this didn't work, because integer variables are constants (I'm not sure of the exact way to describe things):

>>> a = 1
>>> b = 1
>>> a is b
True
>>> b is a
True
>>> a == b
True

How might I accomplish this?

blacksite
  • 12,086
  • 10
  • 64
  • 109

4 Answers4

1
import itertools

data = range(5)

result = {f"a{count}": value for count, value in zip(itertools.count(1), data)}

print(result)

Output:

{'a1': 0, 'a2': 1, 'a3': 2, 'a4': 3, 'a5': 4}
ForceBru
  • 43,482
  • 10
  • 63
  • 98
  • Perhaps my example was *too* simplistic. What if `a` and `b` are really something like `ip_address` and `my_dogs_name`? This approach would lose that very valuable information. – blacksite Feb 07 '19 at 15:25
  • @blacksite, if you want to save all local/global names, use `locals()` and `globals()` respectively and serialize the result – ForceBru Feb 07 '19 at 15:27
1

You might want to look into locals() and inspect. The result could be i.e.:

>>> from inspect import ismodule
>>> a = 1
>>> b = 1
>>> dict((k, v) for k, v in locals().items() if not k.startswith("__") and not callable(v) and not ismodule(v))
{'a': 1, 'b': 1}

But to get it right you might need to add some additional conditions, and also you will have to watch out for mutable objects or values, as in this case those would mutate and you would not preserve the earlier value for later inspection. Serialization or copying them could help.

mfrackowiak
  • 1,294
  • 8
  • 11
1

You could tackle it from the other direction and save all the local variables, using locals() For example

import json
def foo(a=None, bb=None):
    ccc='lots of c'; de=42
    print( json.dumps( locals() ))

foo() generates {"a": null, "bb": null, "ccc": "lots of c", "de": 42}

( json.dumps is one way to serialize a dict, and will work only for simple variables that can be converted to JSON)

Another way to just get some variables would be

print( json.dumps( dict( a=a, b=b, c=c) ))
nigel222
  • 7,582
  • 1
  • 14
  • 22
0

Here is another way using ascii_lowercase from string module:

import string

alphabets = iter(string.ascii_lowercase)
lookup = {next(alphabets): x for x in range(5)}

print(lookup)
# {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4}
Austin
  • 25,759
  • 4
  • 25
  • 48