1

How can I give a dictionary a name from a variable value?

An example of what I'm trying to build:

apache['name'] = "Apache Web Server"
apache['category'] = "web"
apache['version'] = "2.2.14-4"

However I don't know the dictionary's name in advance, that arrives as variable, e.g. dname = 'apache'. Dname is parsed from a text file. The logic is: "First word after delimiter is dict_name; next n lines are split into key:value pairs for dict_name; skip to next delimiter; repeat until end".

What doesn't work:

key = 'category'
value = 'web'

dname[key] = value

TypeError: 'str' object does not support item assignment

eval(dname)[key] = value

NameError: name 'apache' is not defined

getattr(dname, '__contains__')[key] = value

and similar attempts with keywords from dir(dname) spawn only errors. (Because getattr is only for functions and modules?)

From How to create a dictionary based on variable value in Python I'm introduced to vars(), but it wants the dictionary to exist already?

vars(dname)[key] = value

TypeError: vars() argument must have __dict__ attribute

This question's title is the closest sounding I've found to what I'm after, but the answers are about using variables for keys, not the dict name: Create a dictionary with name of variable

Community
  • 1
  • 1
matt wilkie
  • 17,268
  • 24
  • 80
  • 115
  • To give us some context, where does it "arrive" from? – NPE Nov 02 '14 at 08:39
  • @NPE it's parsed from a text file: "First word after delimiter is dict_name; next _n_ lines are split into key:value pairs for dict_name; skip to next delimiter; repeat until end" – matt wilkie Nov 02 '14 at 08:45
  • Oh, so you want to *create* a dictionary with this name? – NPE Nov 02 '14 at 08:46
  • There's already an answer here. http://stackoverflow.com/questions/11553721/using-a-string-variable-as-a-variable-name – Quentin Engles Nov 02 '14 at 09:00
  • Why don't you just put the dictionary in another dictionary, where `'apache'` is the key? – jonrsharpe Nov 02 '14 at 09:01
  • @QuentinEngles which answer do you think answers my Q? The highest voted is about using variable for key name, not dict name; the `setattr` answer yields an error for me (the poster does note it probably only works in a class); and the remaining I haven't tried because it's been resoundingly noted as a bad idea. – matt wilkie Nov 02 '14 at 09:10
  • @jonrsharpe because I need to give 'apache' multiple attributes of it's own (or I don't understand your suggestion?) – matt wilkie Nov 02 '14 at 09:11
  • Technically none, but there are two valid ones. exec(name+' = dictname') or store the dict in another dict like @jonrsharpe says. – Quentin Engles Nov 02 '14 at 09:12
  • @mattwilkie so you'd have e.g. `{'apache': {'name': "Apache Web Server", 'category': "web", 'version': "2.2.14-4"}}`. – jonrsharpe Nov 02 '14 at 09:13
  • If you have the dict, but not in a variable you can do exec(name+'={}'); – Quentin Engles Nov 02 '14 at 09:14

1 Answers1

2

From the discussion in the comments, it is clear that you're trying to create a variable whose name is contained in another variable.

The following shows how this can be done:

d = {}
d["name"] = "Apache Web Server"
d["category"] = "web"
d["version"] = "2.2.14-4"

locals()["apache"] = d

print apache

This creates a local variable, but also take a look at globals().

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 1
    It will not work, if this code is placed inside a function – stalk Nov 02 '14 at 08:53
  • @stalk: First of all, the requirements are not at all clear; it could well be that a local variable is all the OP requires. Secondly, see the last sentence of the answer. – NPE Nov 02 '14 at 08:54
  • Hm, i think modifying `globals()` from function is not a best idea – stalk Nov 02 '14 at 08:56
  • @stalk: Posting vague objections is not very constructive. If you have a better solution, please post it as an answer (I for one would be happy to upvote it if it's good). – NPE Nov 02 '14 at 08:57
  • according to [this](http://stackoverflow.com/a/1450304/821594) answer, it is not possible to create local variables inside a function at runtime. So, why are you modifing `locals` and not `globals` at global namespace? I suppose, they are the same here. – stalk Nov 02 '14 at 09:03
  • thanks for the pointer, it's certainly farther than I've been able to get in the last few hours on my own. I am (intending) to use this in a function. I see that simply replacing `locals()` with `globals()` gives me results. I guess I'll find out if using global namespace gives me other troubles ;-) – matt wilkie Nov 02 '14 at 09:13
  • accepting because it answers the question as asked, though I've since discovered I can't use it because some of the incoming names contain illegal characters (can't have a dict named"foo-bar"). I'm going to have to rethink the whole idea :-/ – matt wilkie Nov 03 '14 at 06:46