Looking up a dictionary _key_ by key?

Steven D'Aprano steve at pearwood.info
Tue Jun 23 22:26:45 EDT 2015


On Wed, 24 Jun 2015 11:32 am, MRAB wrote:

> On 2015-06-24 01:21, Dan Stromberg wrote:
>> I know that sounds strange: usually we look up values by key, not keys.
>>
>> But suppose you have a strange key type that despite being "equal", is
>> not identical in some fields, and you need to see those fields.
>>
>> Is there a way of getting the key used by the dictionary, short of
>> storing a reference to it in the value, or using a second dictionary?
>>
> Yes!
> 
> Start with a dict:
> 
>  >>> d = {1.0: 'one', 2: 'two', 3+0j: 'three'}
>  >>> d[1]
> 'one'
>  >>> d[2]
> 'two'
>  >>> d[3]
> 'three'
> 
> Suppose we want the key that matches 3:
> 
>  >>> k = 3
> 
> Get the keys as a set:
> 
>  >>> s = set(s)
>  >>> s
> {1.0, 2, (3+0j)}


What's s?

I think you mean, s = set(d), which will work. You could also use a key
view:

# Python 2
s = d.viewkeys()

# Python 3
s = d.keys()


> Using intersection doesn't return what we want:
> 
>  >>> s & {k}
> {3}
>  >>> {k} & s
> {3}
> 
> so we have to get creative.
> 
> Remove the keys that _don't_ match:
> 
>  >>> s - {k}
> {1.0, 2}
> 
> and then remove them from the set:
> 
>  >>> s - (s - {k})
> {(3+0j)}
> 
> Finally, get the key:
> 
>  >>> (s - (s - {k})).pop()
> (3+0j)
> 
> Simple, really! :-)


That's certainly creative, but I'm not sure if it will be faster than a
linear search if you have a big dict with millions of keys. Still, it's a
nice trick, and it works with views:


py> d = {1.0: 'one', 2: 'two', 3+0j: 'three'}
py> (d.viewkeys() - (d.viewkeys() - {3})).pop()
(3+0j)




-- 
Steven




More information about the Python-list mailing list