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