views:

1198

answers:

7

I'm wondering how I would go about finding the variable name of a dictionary element:

For example:

    >>>dict1={}
    >>>dict2={}

    >>>dict1['0001']='0002'
    >>>dict2['nth_dict_item']=dict1
    >>>print dict2
    {'nth_dict_item': {'0001': '0002'}}
    >>>print dict2['nth_dict_item']
    {'001': '002'}

How can I go about making it tell me that dict2['nth_dict_item'] is or is referencing "dict1" ? I want the name of the data structure it's referencing and not the data itself.

If I compare the output of id(dict1) to id(dict2['nth_dict_item']) I can find they are the same.

But how can I turn that id back into a variable name? Is there a more direct/cleaner method of getting the information that I want to know?

I'm sure I'm just overlooking a function that would make my life easy but I'm pretty new to Python :)

Any help is appreciated, thanks!

Related


Update: Here's why I wanted this to work:

I'm trying to make an app that uses a dictionary kinda like a database. I wanted the functionality of this psuedocode to function:

dict_1={}
dict_2={}
dict_3={}

dict_1["FooBar1.avi"]=[movie_duration,movie_type,comments]
dict_2["FooBar2.avi"]=[movie_duration,movie_type,comments]
dict_3["FooBar3.avi"]=[movie_duration,movie_type,comments]

dict_database[SomeUniqueIdentifier1]=dict_1
dict_database[SomeUniqueIdentifier2]=dict_2
dict_database[SomeUniqueIdentifier3]=dict_3

SomeUniqueIdentifier# would be a unique value that I'm using as a database key/unqiueID to look up entries.

I want to be able to update the "comments" field of FooBar1.avi by:

WhichDict= dict_database[SomeUniqueIdentifier1]
WhichDict[WhichDict.keys()[0]][2]='newcomment'

instead of having to do:

dict_database['SomeUniqueIdentifier1'][dict_database['SomeUniqueIdentifier1'].keys()[0]][2]='newcomment'


Thanks everyone. I now understand I was misunderstanding a LOT of basics (total brain fart). Will go back and fix the design. Thanks to you all!.

+8  A: 

A variable name is just a name--it has no real meaning as far as the program is concerned, except as a convenience to the programmer (this isn't quite true in Python, but bear with me). As far as the Python interpreter is concerned, the name dict1 is just the programmer's way of telling Python to look at memory address 0x1234.

Furthermore, the very idea of turning a memory address (0x1234) back into a variable name (dict1) doesn't make sense, especially considering that more than one variable name can reference the same object:

dict1 = {...}
dictCopy = dict1

Now dictCopy is just as much the name of the dictionary as dict1 is--they both reference the same thing. If the function you're looking for existed, which name should Python choose?

zenazn
+7  A: 

To add what zenazn said:

But how can I turn that id back into a variable name?

The short answer is that you don't want really want to. If you think you need to, there's something very wrong with the design of your program. If you told us more concretely what problem you were trying to solve, we could help you work out a better way to accomplish it.

Miles
A: 

How can I go about making it tell me that dict2['nth_dict_item'] is or is referencing "dict1" ?

>>> print dict2['nth_dict_item'] is dict1
True
dangph
the problem is in the real usage, i wouldn't know to compare it to dict1 (if i knew that, I wouldn't need this information reported back)
Brandon K
+1  A: 

You need to rethink your design.

A quick hack would be to actually put the variable name in ...

dict2['item_n'] = 'dict1'

or maybe use a tuple ..

dict2['item_n'] = ('dict1', dict1)

There's a function called locals() which gives a dictionary of local variable names, maybe you can consider it when you rethink about your design.

Here, have a look at how locals() works:

>>> x = 10
>>> y = 20
>>> c = "kmf"
>>> olk = 12
>>> km = (1,6,"r",x)
>>> from pprint import pprint
>>> pprint( locals() )
{'__builtins__': <module '__builtin__' (built-in)>,
 '__doc__': None,
 '__name__': '__main__',
 'c': 'kmf',
 'km': (1, 6, 'r', 10),
 'olk': 12,
 'pprint': <function pprint at 0x016A0EB0>,
 'x': 10,
 'y': 20}


UPDATE

I want to be able to update the "comments" field of FooBar1.avi by:

WhichDict= dict_database[SomeUniqueIdentifier1]
WhichDict[WhichDict.keys()[0]][2]='newcomment'

Well, this is trivial

dict_databse[identifier][2] = the_new_comment

hasen j
doesn't display that I need, when dealing with a nested data structure
Brandon K
+4  A: 

The trivial answer: instead of

WhichDict[WhichDict.keys()[0]][2]='newcomment'

use:

WhichDict.values()[0][2]='newcomment'

But using a dictionary to represent a single movie is grossly inappropriate. Why not use a class instead?

class Movie(object):
    def __init__(self, filename, movie_duration, movie_type, comments):
        self.filename = filename
        self.movie_duration = movie_duration
        self.movie_type = movie_type
        self.comments = comments

database = dict()
database['unique_id_1'] = Movie("FooBar1.avi", duration, type, comments)
# ...

some_movie = database[some_id]
some_movie.comment = 'newcomment'
Miles
I need the ability to have users create additional properties for each movie (rating, data watched) etc. wouldn't adding these additional properties to the class be difficult?
Brandon K
You don't have to modify the class to add additional properties to an object; you can just say some_movie.rating = 4
Miles
I'm confused. Since the class doesn't have the property 'rating', how can 4 be assigned to it? Am I missing a fundamental aspect of classes?
Brandon K
At no point are any of the attributes declared on the class; the initializer sets them directly on the Movie instance (passed to the __init__ function as self). Instances of Python classes have internal dictionaries where their attributes are stored, so there's no need to declare them.
Miles
See http://docs.python.org/tutorial/classes.html#class-objects and the next section, instance objects--but it is a very good idea to read the entire tutorial, or an equivalent introduction.
Miles
Seems odd that this answer has so few votes. +1 from me. Nice work.
Adam Bernier
+1  A: 

Right now, for each movie, you're doing:

dict_n = {}
dict_n["000n"] = [movie_duration,movie_type,comments]

with only one entry per dict. Then you're storing multiple movie dicts in a central one:

dict_database = {}
dict_database["0001"] = dict_1
dict_database["0002"] = dict_2
dict_database["0003"] = dict_3
dict_database["000n"] = dict_n

Edit: This is probably what you had in mind.

For each movie, there's a dict going from property names to values.

movie_n = {}
movie_n["movie_duration"] = 333
movie_n["movie_type"] = "Fantasy"
movie_n["comments"] = ""

Then movies["any_file.avi"] gives you that dict. To add the movie to the directory and then add a comment, you enter:

movies["any_file.avi"] = movie_n
movies["any_file.avi"]["comments"] = "new comment"

If you have to choose between the number of that movie and the filename, I'd go with the filename because it's simply more relevant when you're actually trying to access a movie. Plus, if necessary you can enumerate your movies (albeit out of order) through movies.keys() or something similar. If you want to use both a number and the filename, add the filename as another key for each movie.

movie_n["filename"] = "any_file.avi"

or

movies["000n"]["filename"] = "any_file.avi"
Nikhil Chelliah
Then it would seem I loose the ability to reference a movie and its properties by filename. as your dict_database entries no longer contains the movie filename. i'd then have to have a dictionary relating dict_database index keys to filenames ...which is what i'm already doing?
Brandon K
Thanks for your help. I was having a total brain fart and forgetting some of the basics. Thanks for your time.
Brandon K
A: 

Use Guppy.

from guppy import hpy
h=hpy()
h.iso(dict2['nth_dict_item']).sp

0: h.Root.i0_modules['__main__'].__dict__['dict1']
vartec