storing meta data on dictionary keys

Erik Jones erik at myemma.com
Wed Oct 10 00:18:37 EDT 2007


On Oct 9, 2007, at 7:37 PM, Andreas Kraemer wrote:

> From: Chris Mellon <arkanes at gmail.com>
> Sent: Tuesday, October 9, 2007 1:51:04 PM
>
> > Because, by definition, if you have the key then you don't need  
> to get
> > it from the dict. What you're doing here is conflating 2 mappings  
> into
> > one: string value->person and person->values.  Use 2 explicit  
> dicts to
> > make it clear what you're going, or use one dict and store a  
> tuple of
> > values: person, friends = d["John"].
>
> No, that was not the point.
>
> I don't want the meta data to be used in the dictionary look-up,  
> and in fact I want to be able to modify or delete it later w/o  
> affecting dictionary look-up. In the toy example "John" and Str 
> ("John") are two different objects that map to the same value in  
> the dictionary, and "John" == Str("John") is True, since class Str 
> (str)  inherits __hash__() and __eq__() from str. IOW, if John dyes  
> his hair, his friends shouldn't change :-)
>
> Apart from this silly example I really encountered this issue when  
> using the networkx library. As I mentioned, graph nodes are stored  
> as dictionary keys there, i.e. nodes can be arbitrary objects with  
> the only requirement to be hashable, and I am stuck with this data  
> structure when using the library. In my example nodes are uniquely  
> identified by their name (a string) but may carry other attributes,  
> like their display color and shape, that are not used to identify a  
> node. Therefore, I thought, subclassing str would be the simplest,  
> most straightforward structure for a node object.
>
> Of course there are workarounds (e.g. get all keys with keys()),  
> but I thought something similar to a get_key() dictionary method  
> would be the easiest way to retrieve the actually stored key  
> object, and I was just surprised to discover that no such method  
> does exist ....

So, do you not keep references to your nodes anywhere but the actual  
graph dict?  I kind of agree with Chris here in that two dicts will  
work.  One for the nodes, indexed by their strings.  And, to use the  
actual nodes as keys simply override __hash__ in your Node object  
classes.

 >>> class Node(object):
...     def __init__(self, name, **kwargs):
...         self.name = name
...         for k, v in kwargs.items():
...             self.__dict__[k] = v
...
...     def __hash__(self):
...         return hash(self.name)
...
 >>> nodes = {}
 >>> graph = {}
 >>>
 >>> n = Node('foo')
 >>> m = Node('blah', baz=5)
 >>>
 >>> nodes[n.name] = n
 >>> nodes[m.name] = m
 >>>
 >>> for name, node in nodes.items():
...     graph[node] = "whatever for node %s" % name
...
 >>> nodes{'blah': <__main__.Node object at 0x76c50>, 'foo':  
<__main__.Node object at 0x76d30>}
 >>> graph{<__main__.Node object at 0x76c50>: 'whatever for node  
blah', <__main__.Node object at 0x76d30>: 'whatever for node foo'}
 >>> graph[nodes['foo']]'whatever for node foo'

Erik Jones

Software Developer | Emma®
erik at myemma.com
800.595.4401 or 615.292.5888
615.292.0777 (fax)

Emma helps organizations everywhere communicate & market in style.
Visit us online at http://www.myemma.com





More information about the Python-list mailing list