[Tutor] generate a list/dict with a dynamic name..
Steven D'Aprano
steve at pearwood.info
Sun Sep 27 19:40:31 CEST 2015
On Sun, Sep 27, 2015 at 12:38:05PM -0400, bruce wrote:
> Hi.
>
> I can do a basic
> a=[]
> to generate a simple list..
>
> i can do a a="aa"+bb"
>
> how can i do a
> a=[]
>
> where a would have the value of "aabb"
>
> in other words, generate a list/dict with a dynamically generated name
You don't. That is a mistake. How would you use it? Suppose you could
wave a magic wand and create such a variable:
make_variable("aabb", 23) # this doesn't actually work
print aabb # prints 23
But what is the point of doing that? Since you already know the variable
name, just do it the good old fashioned way:
aabb = 23
print 23
"Ah," you say, "but what if I don't know what the name is until the
program actually runs?"
name = random.choice(['fred', 'barney', 'wilma', 'betty'])
make_variable(name, 23)
print ... # err, what the hell do I put here???
You can see the problem. `print name` doesn't work, since that will
print the name itself (say, 'fred'). Working with dynamically generated
names is just a nightmare. You **really** don't want to do there.
But... if you insist, and really want to shoot yourself in the foot...
Python does give you the magic wand to do it. (But please don't.)
In fact, two magic wands. Here's the first, using eval and exec:
py> name = "fred"
py> exec("%s = 23" % name)
py> eval(name)
23
But don't do that:
(1) It's confusing to anyone who has to understand your code.
(2) It's really hard to debug when something goes wrong.
(3) It's slow. About 10 times slower than regular Python code.
(4) It may be a security risk.
If the code you exec() or eval() ever comes from an untrusted users
(say, in a web application), you have just opened a serious back door
into your computer.
Here's another way:
py> name = "fred"
py> globals()[name] = 42
py> print globals()[name]
42
That's a bit better, but still, don't do it.
However, it does give us a clue how to do this safely. Instead of using
a global variable, we keep track of our "dynamic variables" in their own
custom namespace. (A namespace is just a fancy word for an isolated
collection of named things, i.e. variables.)
py> ns = {}
py> name = 'wilma'
py> ns[name] = 999
py> ns[name] += 1
py> print ns['wilma']
1000
By doing it this way, you can still dynamically generate your names, but
keep them isolated from the rest of the program. And you can easily
print out all your "variables" to see what's going on:
py> print ns
{'wilma': 1000}
It's just an ordinary dict.
--
Steve
More information about the Tutor
mailing list