473,327 Members | 2,112 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,327 software developers and data experts.

[dictionary] how to get key by item

saluton al ciuj

i know how to get item by key

==================
dict = {10 : 50, 2 : 12, 4 : 43}

print dict[2]
12
but i wonder how to get key by item

print dict[12]
2

==================
is there a more fast way than that one (my dictionary is really big)
==================
dict = {10 : 50, 2 : 12, 4 : 43}
item = 12
for key in dict.keys():
if dict[key] == item:
print key
break
==================
Jul 18 '05 #1
11 10428

Egor> i know how to get item by key
...
Egor> but i wonder how to get key by item

Assuming your dictionary defines a one-to-one mapping, just invert it:
forward = {10 : 50, 2 : 12, 4 : 43}
reverse = dict([(v,k) for (k,v) in forward.iteritems()])
print forward {10: 50, 4: 43, 2: 12} print reverse

{50: 10, 43: 4, 12: 2}

That doubles your storage, so you'll have to trade that off against the
speed gain of not having to loop over the entire dictionary.

Skip
Jul 18 '05 #2
In article <ma**************************************@python.o rg>,
Skip Montanaro <sk**@pobox.com> wrote:
Egor> i know how to get item by key
...
Egor> but i wonder how to get key by item

Assuming your dictionary defines a one-to-one mapping, just invert it:
>>> forward = {10 : 50, 2 : 12, 4 : 43}
>>> reverse = dict([(v,k) for (k,v) in forward.iteritems()])
>>> print forward {10: 50, 4: 43, 2: 12} >>> print reverse

{50: 10, 43: 4, 12: 2}

That doubles your storage, so you'll have to trade that off against the
speed gain of not having to loop over the entire dictionary.


Well, you *do* loop over the entire dictionary, but you only do it once,
when you create the reverse dict. If you are only going to do a single
lookup, it's no gain, but if you amortize the cost over many lookups,
it's almost certainly a big win.

This raises an interesting question. Let's assume that you add all the
entries to the dictionary before you do any lookups, and you then need
to lookup things up in both directions. Which is faster, to
simultaneously build both the forward and reverse dicts, or to just
build the forward one and when you're done doing that, build the reverse
one in a single shot with the above list comprehension?

BTW, does Python really build the intermediate list and throw it away
after using it to initialize the dictionary, or is it smart enough to
know that it doesn't really need to build the whole list in memory?
Jul 18 '05 #3
That doubles your storage, so you'll have to trade that off against
the speed gain of not having to loop over the entire dictionary.


Roy> Well, you *do* loop over the entire dictionary, but you only do it
Roy> once, when you create the reverse dict. If you are only going to
Roy> do a single lookup, it's no gain, but if you amortize the cost over
Roy> many lookups, it's almost certainly a big win.

Sure, but the OP said his dictionary was big. It's up to him to decide
whether the space-time tradeoff is worth it (or even possible).

Roy> BTW, does Python really build the intermediate list and throw it
Roy> away after using it to initialize the dictionary, or is it smart
Roy> enough to know that it doesn't really need to build the whole list
Roy> in memory?

That's why I called .iteritems() in my example. It won't generate the
entire list of tuples as .items() would.

Skip

Jul 18 '05 #4
Skip Montanaro <sk**@pobox.com> wrote:
Roy> BTW, does Python really build the intermediate list and throw it
Roy> away after using it to initialize the dictionary, or is it smart
Roy> enough to know that it doesn't really need to build the whole list
Roy> in memory?

That's why I called .iteritems() in my example. It won't generate the
entire list of tuples as .items() would.


I know it won't generate the list of items from the forward dict, but I
was thinking of the list generated by the list comprehension, passed as
the argument to the reverse dict constructor. That's the throw-away
list I was thinking of (see Tim Delaney's response to my post).
Jul 18 '05 #5
In article <ma**************************************@python.o rg>,
Skip Montanaro <sk**@pobox.com> wrote:

Assuming your dictionary defines a one-to-one mapping, just invert it:
>>> forward = {10 : 50, 2 : 12, 4 : 43}
>>> reverse = dict([(v,k) for (k,v) in forward.iteritems()])
>>> print forward {10: 50, 4: 43, 2: 12} >>> print reverse

{50: 10, 43: 4, 12: 2}

That doubles your storage, so you'll have to trade that off against the
speed gain of not having to loop over the entire dictionary.


To be precise, it doubles the storage of the *dictionary*, but it does
*NOT* double the storage of the keys and items. Depending on how big
those are, the cost of building a second dict might be mostly lost in the
noise.
--
Aahz (aa**@pythoncraft.com) <*> http://www.pythoncraft.com/

"19. A language that doesn't affect the way you think about programming,
is not worth knowing." --Alan Perlis
Jul 18 '05 #6
Skip Montanaro wrote:
Egor> i know how to get item by key
...
Egor> but i wonder how to get key by item

Assuming your dictionary defines a one-to-one mapping, just invert it:
>>> forward = {10 : 50, 2 : 12, 4 : 43}
>>> reverse = dict([(v,k) for (k,v) in forward.iteritems()])
>>> print forward {10: 50, 4: 43, 2: 12} >>> print reverse

{50: 10, 43: 4, 12: 2}

That doubles your storage, so you'll have to trade that off against the
speed gain of not having to loop over the entire dictionary.

Skip


But beware that all the items in the original dictionary must be
hashable. The example shows just integers, so I assume they are in this
case. But generally, this may not work.

--
\/ \/
(O O)
-- --------------------oOOo~(_)~oOOo----------------------------------------
Keith Dart <kd***@kdart.com>
vcard: <http://www.kdart.com/~kdart/kdart.vcf>
public key: ID: F3D288E4 URL: <http://www.kdart.com/~kdart/public.key>
================================================== ==========================
Jul 18 '05 #7
Skip Montanaro wrote:
That doubles your storage


careful: it creates another dictionary structure with the same size as the first
one, but it doesn't copy the objects in the dictionary.

so whether it doubles the actual memory usage depends on what data you
have in the dictionary (last time I checked, ints and dictionary slots were the
same size, but I cannot think of any other object that isn't larger...)

(but you knew that, of course)

</F>

Jul 18 '05 #8
Skip Montanaro wrote:
Egor> i know how to get item by key
...
Egor> but i wonder how to get key by item

Assuming your dictionary defines a one-to-one mapping, just invert it:
>>> forward = {10 : 50, 2 : 12, 4 : 43}
>>> reverse = dict([(v,k) for (k,v) in forward.iteritems()])
>>> print forward {10: 50, 4: 43, 2: 12} >>> print reverse

{50: 10, 43: 4, 12: 2}

That doubles your storage, so you'll have to trade that off against the
speed gain of not having to loop over the entire dictionary.

Skip


If some keys has the same value as the item this will cause problems
because keys in your result dictionary can be overwritten. Could it be a
option to build the result dictionary as a dictionary with the values
as the keys, and lists of keys as the value. Perhaps you need to use a
loop for this.

--
--------------------------------------
Ola Natvig <ol********@infosense.no>
infoSense AS / development
Jul 18 '05 #9
Ola Natvig wrote:
If some keys has the same value as the item this will cause problems
because keys in your result dictionary can be overwritten. Could it be a
option to build the result dictionary as a dictionary with the values
as the keys, and lists of keys as the value. Perhaps you need to use a
loop for this.


<<Python 2.4>>

..>>> d = dict(foo=1, bar=1, bob=7, jane=42, mary=16, fred=16)
..>>> from itertools import groupby
..>>> val = d.__getitem__
..>>> grouped = groupby(sorted(d.iterkeys(), key=val), val)
..>>> r = dict((value, list(keys)) for value, keys in grouped)
..>>> r
{16: ['mary', 'fred'], 1: ['bar', 'foo'], 42: ['jane'], 7: ['bob']}

Cheers,
Nick.

--
Nick Coghlan | nc******@email.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #10

Fredrik> Skip Montanaro wrote:
That doubles your storage


Fredrik> careful: it creates another dictionary structure with the same
Fredrik> size as the first one, but it doesn't copy the objects in the
Fredrik> dictionary.

Yes, sorry. The OP indicated the original dictionary was very big, so it
seemed like duplicating the dictionary storage would potentially be costly
since dictionaries hold extra storage (on average, twice the storage needed
to hold the references to its keys?) to support O(1) average time lookup.

Skip
Jul 18 '05 #11

Ola> If some keys has the same value as the item this will cause
Ola> problems because keys in your result dictionary can be
Ola> overwritten.

That's why I said, "assuming your dictionary defines a one-to-one
mapping...".

Skip
Jul 18 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: none | last post by:
or is it just me? I am having a problem with using a dictionary as an attribute of a class. This happens in python 1.5.2 and 2.2.2 which I am accessing through pythonwin builds 150 and 148...
1
by: boohoo | last post by:
I can't seem to do this: I want to take a query string and place two halves of the querystring into two separate dictionary objects. So... I loop through the collection of querystring items,...
5
by: Fox | last post by:
Hi, I am working on a project which used dictionaries. I am having to remake part of this and have no experience with the scripting dictionary. I need to see how to create multiple...
1
by: john wright | last post by:
I have a dictionary oject I created and I want to bind a listbox to it. I am including the code for the dictionary object. Here is the error I am getting: "System.Exception: Complex...
4
by: Martin Widmer | last post by:
Hi folks. I am using this collection class: Public Class ContentBlocksCollection Inherits DictionaryBase 'Object variables for attributes 'Attributes Default Public Property Item(ByVal...
1
by: Martin Widmer | last post by:
Hi Folks. When I iterate through my custom designed collection, I always get the error: "Unable to cast object of type 'System.Collections.DictionaryEntry' to type...
1
by: Dan Holmes | last post by:
I have a custom dictionary and i would like to bind it to a control. Since Dictionary doesn't implement IList i would have to write it. Is the only way to do this to keep another collection that...
5
by: davenet | last post by:
Hi, I'm new to Python and working on a school assignment. I have setup a dictionary where the keys point to an object. Each object has two member variables. I need to find the smallest value...
2
by: =?Utf-8?B?U2hhd24=?= | last post by:
Hi; I would like to be able to use the XMLSerializer to serialize and deserialize a dictionary. is that possible? i know that you can serialize an object that implements the ICollection interface....
6
by: dudeja.rajat | last post by:
Hi, How to check if something is a list or a dictionary or just a string? Eg: for item in self.__libVerDict.itervalues(): self.cbAnalysisLibVersion(END, item) where __libVerDict is a...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.