Re: Dictionary bidirectional
If keys and values are unique, maybe just store both in the same dictionary: mydict[a] = b mydict[b] = a ... Gerry On Jul 14, 8:31 am, Impotent Verse <[EMAIL PROTECTED]> wrote: > If keys and values are unique you could do this... > > -- > > # Left : Right > roman = { "One" : "I", > "Two" : "II", > "Three" : "III", > "Four" : "IV", > "Five" : "V", > "Six" : "VI", > "Seven" : "VII", > "Eight" : "VIII", > "Nine" : "IX", > "Ten" : "X" } > > left, right = zip( *roman.items() ) > left = list(left) > right = list(right) > > print left[ right.index("VIII") ] > > -- > > ... result is "Eight". > > Hmmm! zip returns tuples, which need to be turned into lists to do > much with. Maybe not the best solution in this case. > > Verse. -- http://mail.python.org/mailman/listinfo/python-list
Re: Dictionary bidirectional
This is a better version of the class that I sen't you, now it raises a KeyError when you try to insert a value that is already in class MyCoolDictionary(dict): def __init__(self, *args, **kargs): dict.__init__(self, *args, **kargs) def __setitem__(self, *args, **kargs): for i in dictio.values(): if args[0]==i or args[1]==i: raise KeyError, 'Value already exists' dict.__setitem__(self, *args, **kargs) def __getitem__(self, item): try: return dict.__getitem__(self, item) except KeyError: keys=[] for i in dictio.keys(): if dictio[i]==item: keys.append(i) if not keys: raise KeyError, 'Can\'t found key or value "' + str(item) + '"' return keys Feel free to change anything you want or need Regards, Akathorn Greyhat 2008/7/14 Kless <[EMAIL PROTECTED]>: > I need a dictionary where get the result from a 'key' (on left), but > also from a 'value' (on right), how to get it? > > I know that dictionaries aren't bidirectional, but is there any way > without use two dictionaries? > > > Thanks in advance! > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list
Re: Dictionary bidirectional
If keys and values are unique you could do this... -- # Left : Right roman = { "One" : "I", "Two" : "II", "Three" : "III", "Four": "IV", "Five": "V", "Six" : "VI", "Seven" : "VII", "Eight" : "VIII", "Nine": "IX", "Ten" : "X" } left, right = zip( *roman.items() ) left = list(left) right = list(right) print left[ right.index("VIII") ] -- ... result is "Eight". Hmmm! zip returns tuples, which need to be turned into lists to do much with. Maybe not the best solution in this case. Verse. -- http://mail.python.org/mailman/listinfo/python-list
Re: Dictionary bidirectional
Akathorn Greyhat sent me by email the next solution, which althought isn't generic it works well: - You could make your own class for that, maybe something like # class MyCoolDictionary(dict): def __init__(self, *args, **kargs): dict.__init__(self, *args, **kargs) def __getitem__(self, item): try: return dict.__getitem__(self, item) except KeyError: keys=[] for i in dictio.keys(): if dictio[i]==item: keys.append(i) return keys dictio=MyCoolDictionary({"a" : 1, "b" : 2, "c" : 2}) print dictio["a"] print dictio["b"] print dictio[1] print dictio[2] # The output of this code is: 1 2 ['a'] ['c', 'b'] Note that it isn't finish, maybe you'll need to make some kind of test before adding a new value because with this code one value can have multiple keys, and I have fixed it by returning a list of keys instead a single value. It's up to you =) I'm sorry of my poor english =( Regards, Akathorn Greyhat - -- http://mail.python.org/mailman/listinfo/python-list
Re: Dictionary bidirectional
Larry Bates: > The only case where it would be faster would be if most of the keys were NOT > in > the dictionary (rather odd use case). Otherwise I believe you will find the > first way quicker as the exceptions are infrequent. I have written a small benchmark: from random import shuffle def test1(data, to_delete): for item in to_delete: try: del data[item] except KeyError: pass def test2(data, to_delete): for item in to_delete: if item in data: del data[item] N = 100 M = 2 * N data = dict.fromkeys(xrange(N), 0) to_delete = range(M) shuffle(to_delete) from timeit import default_timer as clock t = clock() #test1(data, to_delete) # 2.4 s test2(data, to_delete) # 0.8 s print round(clock() - t, 2), "s" It creates a dictionary of the first million integers, and then tries to delete the first two million of integers. So about 1/2 numbers are present to be deleted. In this situation the version with the try- except seems about 3 times slower than the other. Bye, bearophile -- http://mail.python.org/mailman/listinfo/python-list
Re: Dictionary bidirectional
Dennis Lee Bieber wrote: On Sun, 13 Jul 2008 16:21:11 -0700 (PDT), Kless <[EMAIL PROTECTED]> declaimed the following in comp.lang.python: I need a dictionary where get the result from a 'key' (on left), but also from a 'value' (on right), how to get it? I know that dictionaries aren't bidirectional, but is there any way without use two dictionaries? Just out of curiosity... What do you expect to have returned from... aDict = { "one" : "two", "three" : "four", "What?" : "two" } when looking for the value "two"? In a dictionary, the /keys/ are unique... but the /values/ can be duplicates. I wonder if anyone has implemented an 'equivalence class' class (for finite sets) based on this. Obviously the relation defined by k1~k2 iff D[k1] == D[k2] does partition the set of all keys as an equivalence class. So ... as a kind of inverse you could return a set, a subset of the keys. How you would get a canonical representative of that set is a different matter, of course. Unless, as in the OP's case, it is a singleton set. It would seem more efficient to do this when a key-value pair is added or removed from the original dictionary rather than iterating over all the keys each time you used it. -- http://mail.python.org/mailman/listinfo/python-list
Re: Dictionary bidirectional
But in my dictionary both keys and values are unique. On Jul 14, 7:34 am, Dennis Lee Bieber <[EMAIL PROTECTED]> wrote: > On Sun, 13 Jul 2008 16:21:11 -0700 (PDT), Kless > <[EMAIL PROTECTED]> declaimed the following in comp.lang.python: > > > I need a dictionary where get the result from a 'key' (on left), but > > also from a 'value' (on right), how to get it? > > > I know that dictionaries aren't bidirectional, but is there any way > > without use two dictionaries? > > Just out of curiosity... What do you expect to have returned from... > > aDict = { "one" : "two", > "three" : "four", > "What?" : "two" } > > when looking for the value "two"? > > In a dictionary, the /keys/ are unique... but the /values/ can be > duplicates. -- http://mail.python.org/mailman/listinfo/python-list
Re: Dictionary bidirectional
On Jul 13, 6:53 pm, Larry Bates <[EMAIL PROTECTED]> wrote: > [EMAIL PROTECTED] wrote: > > bukzor: > >> You need to use two dictionaries. Here's a class that someone's > >> written that wraps it up into a single dict-like object for you: > >>http://www.faqts.com/knowledge_base/view.phtml/aid/4376 > > > It contains code like: > > > try: > > del self.data[item] > > except KeyError: > > pass > > > Exceptions are useful in python, but with dictionaries this is > > probably faster (and shorter), even if it may perform two lookups: > > > if item in self.data: > > del self.data[item] > > > Bye, > > bearophile > > The only case where it would be faster would be if most of the keys were NOT > in > the dictionary (rather odd use case). Otherwise I believe you will find the > first way quicker as the exceptions are infrequent. > > -Larry /agree -- http://mail.python.org/mailman/listinfo/python-list
Re: Dictionary bidirectional
-- Forwarded message -- From: Akathorn Greyhat <[EMAIL PROTECTED]> Date: 2008/7/14 Subject: Re: Dictionary bidirectional To: Kless <[EMAIL PROTECTED]> 2008/7/14 Kless <[EMAIL PROTECTED]>: I need a dictionary where get the result from a 'key' (on left), but > also from a 'value' (on right), how to get it? > > I know that dictionaries aren't bidirectional, but is there any way > without use two dictionaries? > > > Thanks in advance! > -- > http://mail.python.org/mailman/listinfo/python-list > You could make your own class for that, maybe something like # class MyCoolDictionary(dict): def __init__(self, *args, **kargs): dict.__init__(self, *args, **kargs) def __getitem__(self, item): try: return dict.__getitem__(self, item) except KeyError: keys=[] for i in dictio.keys(): if dictio[i]==item: keys.append(i) return keys dictio=MyCoolDictionary({"a" : 1, "b" : 2, "c" : 2}) print dictio["a"] print dictio["b"] print dictio[1] print dictio[2] # The output of this code is: 1 2 ['a'] ['c', 'b'] Note that it isn't finish, maybe you'll need to make some kind of test before adding a new value because with this code one value can have multiple keys, and I have fixed it by returning a list of keys instead a single value. It's up to you =) I'm sorry of my poor english =( Regards, Akathorn Greyhat -- http://mail.python.org/mailman/listinfo/python-list
Re: Dictionary bidirectional
[EMAIL PROTECTED] wrote: bukzor: You need to use two dictionaries. Here's a class that someone's written that wraps it up into a single dict-like object for you: http://www.faqts.com/knowledge_base/view.phtml/aid/4376 It contains code like: try: del self.data[item] except KeyError: pass Exceptions are useful in python, but with dictionaries this is probably faster (and shorter), even if it may perform two lookups: if item in self.data: del self.data[item] Bye, bearophile The only case where it would be faster would be if most of the keys were NOT in the dictionary (rather odd use case). Otherwise I believe you will find the first way quicker as the exceptions are infrequent. -Larry -- http://mail.python.org/mailman/listinfo/python-list
Re: Dictionary bidirectional
bukzor: > You need to use two dictionaries. Here's a class that someone's > written that wraps it up into a single dict-like object for you: > http://www.faqts.com/knowledge_base/view.phtml/aid/4376 It contains code like: try: del self.data[item] except KeyError: pass Exceptions are useful in python, but with dictionaries this is probably faster (and shorter), even if it may perform two lookups: if item in self.data: del self.data[item] Bye, bearophile -- http://mail.python.org/mailman/listinfo/python-list
Re: Dictionary bidirectional
On Jul 13, 4:21 pm, Kless <[EMAIL PROTECTED]> wrote: > I need a dictionary where get the result from a 'key' (on left), but > also from a 'value' (on right), how to get it? > > I know that dictionaries aren't bidirectional, but is there any way > without use two dictionaries? > > Thanks in advance! You need to use two dictionaries. Here's a class that someone's written that wraps it up into a single dict-like object for you: http://www.faqts.com/knowledge_base/view.phtml/aid/4376 -- http://mail.python.org/mailman/listinfo/python-list
Re: Dictionary bidirectional
On Jul 13, 4:21 pm, Kless <[EMAIL PROTECTED]> wrote: > I need a dictionary where get the result from a 'key' (on left), but > also from a 'value' (on right), how to get it? > > I know that dictionaries aren't bidirectional, but is there any way > without use two dictionaries? > > Thanks in advance! You want to print the key as well as the value? -- http://mail.python.org/mailman/listinfo/python-list
Dictionary bidirectional
I need a dictionary where get the result from a 'key' (on left), but also from a 'value' (on right), how to get it? I know that dictionaries aren't bidirectional, but is there any way without use two dictionaries? Thanks in advance! -- http://mail.python.org/mailman/listinfo/python-list