0

Question

How can I use keys of a dictionary as the dictionary name and the prior name as the key?

Here's a similar question:
So far I only found this Python bidirectional mapping, which covers the basic function of bidirectional mapping.

I don't want to find the key for values though, but something like this:

dict_one = { 'a': 123, 'b': 234 }
dict_two = { 'a': 567, 'b': 678 }
dict_one['a']
>> 123
dict_two['a']
>> 567
#... some magic (not simply defining a dict called 'a' though)
a['dict_one']
>> 123
a['dict_two']
>> 567

Situation

I have a number of dictionaries storing constants for different objects. Every object has the same properties (or are existent for most objects). In order to ease the calling of constants in loops both described ways would be useful.

Community
  • 1
  • 1
BadAtLaTeX
  • 614
  • 1
  • 9
  • 22
  • 3
    I would suggest modifying your code prior to this so that it doesn't end up with this problem in the first place http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – sshashank124 Apr 19 '15 at 20:12
  • Are there only 2 dicts? If not how do you plan to remember the list of dict variables? – Bhargav Rao Apr 19 '15 at 20:13
  • You could create a function named "a" (`def a(dict_name):`) and use `eval()` to give you access to the Dictionary object based on its name. Would that suffice? – Gord Thompson Apr 19 '15 at 20:31
  • @sshashank124: What would you suggest ? - I can not imagine a better way to store plain constants (see next). At the moment it is mainly a thought - but yes you are right, I ask for `y`. @BhargavRao: No there are several dictionaries (2D table, might extend to more in futur) containing physical constants. Calling `object['property']`, as well as `property['object']` could make life easier in functions dealing with several constants of the same object or vice versa. @GordThompson: Is probably a solution, though it would change the call to `a('object')`, wouldn't it? (One more thing to remember) – BadAtLaTeX Apr 19 '15 at 21:32
  • Yes, using a function would make the call `a('dict_one')` instead of `a['dict_one']`, which is why I posted the suggestion as a comment instead of an answer. – Gord Thompson Apr 20 '15 at 09:00

2 Answers2

1

You shouldn't use the following solution, which modifies globals() (these kind of environment manipulation are error-prone and should be avoided as much as possible!):

dict_one = { 'a': 123, 'b': 234 }
dict_two = { 'a': 567, 'b': 678 }

output = {}
for x in dict_one.keys():
    submap = output.get(x, {})
    submap["dict_one"] = dict_one[x]
    output[x] = submap

for x in dict_two.keys():
    submap = output.get(x, {})
    submap["dict_two"] = dict_two[x]
    output[x] = submap


# part 2
globs = globals()

for x in output:
    globs[x] = output[x]

print a['dict_two'] # 567

What you should do, is simply use output as an abstraction layer (ignore "part 2" of the previous code snippet and instead use):

print output['a']['dict_one'] #123
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
1

You can define your own class inherited from dict to achieve this, and override the __getitem__ method. But this solution too adds variables through the globals dictionary, not a recommended practice as mentioned by others before me.

class mdict(dict):
    def __getitem__(self, item):
        self.normal = dict(self)
        return self.normal[str(globals()[item])]

dict_one = {'a': 123, 'b': 234}
dict_two = {'a': 567, 'b': 678}

lst = [dict_one, dict_two]

for item in lst:
    for k, v in item.iteritems():
        dd = globals().setdefault(k, mdict())
        dd[str(item)] = v


>>> print a['dict_one']
123
>>> print b['dict_one']
234
>>> print a['dict_two']
567
>>> print b['dict_two']
678
Saksham Varma
  • 2,122
  • 13
  • 15