Can dictionary values access their keys?

  • Thread starter Matthew Thorley
  • Start date
M

Matthew Thorley

This may be a very rudimentary question, but here goes:

If I have a simple dictionary, where the value is a class or function,
is there an interface through which it can discover what its key is?
Similar to index() for list.

For a list, assuming I new what the parent list was I could do something
like this.
.... def get_parent_index(self, parent):
.... return parent.index(self)
....
a = child()
l = [a]
b = l[0]
b.get_parent_index(a)
b.get_parent_index(l)
0

Is there a way to do something like that with dicts?


On a similar note, if one object is part of another, is there a way for
the 'child' obj to discover what/who the 'parent' object is? That way
parent does not have to be explicityly passed to get_parent_index?

The idea is like this:
.... def get_parent_index(self):
parent = self.magic_parent_discovery()
.... return parent.index(self)
....



Thanks much
 
D

Diez B. Roggisch

Is there a way to do something like that with dicts?

Not without searching the dict's items through, or keeping a additional
mapping between values and keys.
On a similar note, if one object is part of another, is there a way for
the 'child' obj to discover what/who the 'parent' object is? That way
parent does not have to be explicityly passed to get_parent_index?

No.
 
A

Axel Straschil

Hello!
If I have a simple dictionary, where the value is a class or function,
is there an interface through which it can discover what its key is?

The key of a value may not be unique, so you can also get a tupe of
keys, like dict(a=1, b=1), the key's of 1 are a and b.

For unique values, I did something like that couple of weeks ago, the
thing you would need is the getKey thing, it's fast, but needs much
memory for big structures becouse I use two dicts.
If speed does not matter:

class ReverseDict(dict):
def get_keys(self, value):
keys = []
for k, v in self.items():
if v == value: keys.append(k)
return keys

class UniqueReverseDict(dict):
"""
A dictionary that can resolute reverse: A object to a key. Both, the Key and
the Value must be unique.
"""

def __init__(self, **kws):
super(UniqueReverseDict, self).__init__(kws)
self.__reverse = {}

def __setitem__(self, k, v):
super(UniqueReverseDict, self).__setitem__(k, v)
self.__reverse[v] = k

def __update_reverse(self):
self.__reverse.clear()
for k, v in self.items():
self.__reverse[v] == k

def has_value(self, v):
return self.__reverse.has_key(v)

def __delitem__(self, k):
self.__reverse[self[k]]
super(UniqueReverseDict, self).__delitem__(k)

def clear(self):
self.__reverse.clear()
super(UniqueReverseDict, self).clear()

def copy(self):
return UniqueReverseDict(self)

def pop(self, k):
del self.__reverse[self[k]]
return self.pop(k)

def popitem(self, **kws):
raise 'AxsPy.Misc.Structures.UniqueReverseDict', \
'NotImplemented'

def setdefault(self, **kws):
raise 'AxsPy.Misc.Structures.UniqueReverseDict', \
'NotImplemented'

def update(self, **kws):
super(UniqueReverseDict, self).update(**kws)
self.__update_reverse()

def getKey(self, v): return self.__reverse[v]

Lg,
AXEL
 
D

Diez B. Roggisch

Matthew said:
Can you please elaborate on this?

Eh, just have two dicts that are the inverse of each other. You could do
that by subclassinc dict:

class mydict(dict):
def __init__(self):
self.__inverse_mapping = {}

def __setitem__(self, key, value):
dict.__setitem__(key, value)
self.__inverse_mapping[value] = key


def key4value(self, v):
return self.__inverse_mapping[v]


But of course this only works if your mapping is bijective. Consider this:

d = mydict()
d[10] = 20
print d.key4value(20)
d[15] = 20
print d.key4value(20)

This will of course not give you (10,15), but 15 only - the last mapping
overwrites earlier ones. And beware of non-hashable objects like lists or
dicts themselves, they aren't working as keys. So this produces an error:

d[100] = [1,2,3,4]
TypeError: list objects are unhashable
 
M

Matthew Thorley

Axel said:
For unique values, I did something like that couple of weeks ago, the
thing you would need is the getKey thing, it's fast, but needs much
memory for big structures becouse I use two dicts.

Thanks for the tip, I may give that a try. I'll be interested to see
what kind of speed penalty I pay. The data I am using has multiples
dictionaries with maybe a thousand entries each. But each entry is an
object containing a history of data with perhaps hundreds or even
thousands more entries. So we're talking about maybe a million+ total
nested key:values. I don't know if that counts as large or not. I can't
even guess how much k memory that is.

I must say I am *very* suprised that python does not have a way to look
up what key is pointing to a given object--without scanning the whole
list that is. Is that what list.index() does under-the-hood? I mean is
list.index(y) just the same as

itemnum = 0
for item in list:
if y == item:
return itemnum
else:
itemnum = itemnum+1


I think I am going to have to reevaluate my system design... grrr.

thanks
 
S

Steve Holden

Matthew said:
This may be a very rudimentary question, but here goes:

If I have a simple dictionary, where the value is a class or function,
is there an interface through which it can discover what its key is?
Similar to index() for list.
No, because mapping types (of which dict is the canonical example) don;t
guarantee uniqueness of values. In other words, there can be several
keys mapping to the same value.

You would therefore need to know how to handle such cases - would you
want to return an arbitrary one of those keys, or a list of them all?

A standard dict doesn't keep any record of the order in which keys were
added, so there are some things you *can't* do, like return "the first
key added with a given value".
For a list, assuming I new what the parent list was I could do something
like this.


... def get_parent_index(self, parent):
... return parent.index(self)
...
a = child()
l = [a]
b = l[0]
b.get_parent_index(a)
b.get_parent_index(l)

0

Is there a way to do something like that with dicts?
So you know about the .index() and .find() methods, and of course since
there is no guarantee that a value appears only once in the list they
disambiguate by returning the lowest index containing the value.

A simple way to do what you appear to want would be:

def get_parent_index(self, parent):
for k, v in parent.items():
if v == self:
return k

This would return None if the required item wasn't found in the dict parent.
On a similar note, if one object is part of another, is there a way for
the 'child' obj to discover what/who the 'parent' object is? That way
parent does not have to be explicityly passed to get_parent_index?
This is like asking if you can find the "name" of an object. The fact is
that a single object can be bound to many variables. Suppose I write:

lst = [1, 2, 3]

does that mean that the "name" of 2 is lst[1]? No - 2 is just a value
that happens to be bound to that list element (among other things).

If I then write

otherlst = lst
otherlst[1' = "two"

you will find that lst[1] is also now bound to "two" because lst and
otherlst are in fact references tot he same list object, so changing one
also changes the other. Given that, what is the "name" of that list?
The idea is like this:



... def get_parent_index(self):
parent = self.magic_parent_discovery()
... return parent.index(self)
...

Given a set of objects and a known attribute or set of attributes for
those objects that might be references to a specific search target you
can perform the magic you want, but a generic search for "any reference
to the search target", while not impossible (using Python's excellent
introspection facilities) is way beyond what most people would consider
practical. Obviously the garbage collector has to solve this problem,
but you *really* don't want to be doing this stuff in Python unless you
absolutely *must*.

regards
Steve
 
S

Scott David Daniels

Matthew said:
This may be a very rudimentary question, but here goes:
From your questions, I believe you are not thinking of values as
being distinct from the names and data structures that refer to them.

What is the parent of 23 in the following expression?

1 + 11 * 2

If you know that, what is the parent of 293 in the same expression?
If I have a simple dictionary, where the value is a class or function,
is there an interface through which it can discover what its key is?
Similar to index() for list.

def keyfor(dictionary, element):
for key, value in dictionary.iteritems():
if value == element: # value is element if identity quest
return key
raise ValueError, element
On a similar note, if one object is part of another,
This is the idea you have wrong. In C, C++, Java, and Fortran you
might have objects part of other objects, but in Python objects refer
to each other.

How about this:

class Holder(object): pass

v = [1 + 11 * 2]
w = [1, v, 3]
d = {1: v}
o = Holder()
o.x = v

What is the parent of v?

Or even worse:

v = [1]
v[0] = v

What is the parent of v now?

--Scott David Daniels
(e-mail address removed)
 
A

Axel Straschil

Hello!
thousands more entries. So we're talking about maybe a million+ total
nested key:values. I don't know if that counts as large or not. I can't
even guess how much k memory that is.

Mhh, maybe you should use a SQL-Database ;-)

Lg,
AXEL.
 
M

Matthew Thorley

Steve Holden wrote:
while not impossible (using Python's excellent
introspection facilities) is way beyond what most people would consider
practical. Obviously the garbage collector has to solve this problem,
but you *really* don't want to be doing this stuff in Python unless you
absolutely *must*.

regards
Steve


Thanks very much for the detailed reply. Let me explain in a little more
detail what I am doing, and perhaps you could let me know if I am going
about it the wrong way.


I am creating an object database to store information about network
devices, e.g. switches and routers.

At the top level there are device objects, every device object contains
a mib object--and other various properties--where the actual data is
stored. The mib object is a dicitionary--or at least subclasses
dictionary--where the key is the oid (a unique string) and the value is
a special object called Datapoint. Datapoints come in two types Static
and Dynamic, and every Datapoint is unique.

So a simple structure looks something like this:

Device1
Mib1
{'1.3.6.1':Datapoint-x1,
'1.3.6.2':Datapoint-y1,
'1.1.5.4':Datapoint-z1,
'1.2.7.3':Datapoint-q1}

Device2
Mib2
{'1.3.6.1':Datapoint-x2,
'1.3.6.2':Datapoint-y2,
'1.1.5.4':Datapoint-z2,
'1.2.7.3':Datapoint-q2}

In the example Datapoint-xx should be read as, some unique data point in
memory.

The key in the Mib object is important because it is used by the
Datapoint is points to to look up its current value on the given device,
which is why I asked the two questions.

In my program I use snmp to look up values on network devices. i.e. 'Go
find the value of 1.3.6.1 from device1.' I want to be able to say
something like Device1.Mib['1.3.6.1].update(), and the correct Datapoint
discovers its key (oid) and parent device, then executes an snmp query
that looks something like this snmpget(keyThatPointsToSelf,
parentObj.ipAddress, parentObj.paramx)

I know of course I could keep all this in a relational database and do a
bunch of queries, but that would really suck! and I would have to track
all the Devices and oids my self. What I really want is smart objects
that think for me--thats what computers are for, right? ;)

I thought my design was a wonderfuly beautiful use of python an oop, but
perhaps I am mistaken and there is a much more pragmatic way to get the
job done. In the end preformance doesn't matter a lot. The front end
will be web based, so if the db can process faster than http/javascript
and user Bob who has to mouse, then everything will be fine.

Let me know what you think
Thanks much
--Matthew
 
M

Matthew Thorley

Scott said:
Matthew said:
This may be a very rudimentary question, but here goes:

From your questions, I believe you are not thinking of values as
being distinct from the names and data structures that refer to them.

What is the parent of 23 in the following expression?

1 + 11 * 2

If you know that, what is the parent of 293 in the same expression?
If I have a simple dictionary, where the value is a class or function,
is there an interface through which it can discover what its key is?
Similar to index() for list.


def keyfor(dictionary, element):
for key, value in dictionary.iteritems():
if value == element: # value is element if identity quest
return key
raise ValueError, element
On a similar note, if one object is part of another,

This is the idea you have wrong. In C, C++, Java, and Fortran you
might have objects part of other objects, but in Python objects refer
to each other.

How about this:

class Holder(object): pass

v = [1 + 11 * 2]
w = [1, v, 3]
d = {1: v}
o = Holder()
o.x = v

What is the parent of v?

Or even worse:

v = [1]
v[0] = v

What is the parent of v now?

--Scott David Daniels
(e-mail address removed)

I see what your saying, but I my situation the values of the dictionary
are unique objects created by a parent object. Sorry :(, I didn't
explain that very well in my first post.

When the 'root object' is 'global' I see what your saying, but when

class A:
def __init__(self, container):
self.container=container

class B(dict):
def magice_get_parent(self):
...

class special_value():
def __init__(self, val):
self.val = val

def magic_get_key(self):
...

parent = A(B)
parent.container[x] = special_value(1)
parent.container[y] = special_value(2)
parent.container[z] = special_value(1)


In this example, in my mind, the following should happen, and in theory
using introspecition, actualy possible.

child = parent.container
D.magic_get_parent() #returns parent


value1 = parent.container[x]
value2 = parent.container[y]
value3 = parent.container[z]

value1.magic_get_key() #returns x
value2.magic_get_key() #returns y
value3.magic_get_key() #returns z

Let me know if I'm nutz!
--Matthew
 
S

Steve Holden

Matthew said:
Steve Holden wrote:
while not impossible (using Python's excellent
introspection facilities) is way beyond what most people would consider
practical. Obviously the garbage collector has to solve this problem,
but you *really* don't want to be doing this stuff in Python unless you
absolutely *must*.

regards
Steve



Thanks very much for the detailed reply. Let me explain in a little more
detail what I am doing, and perhaps you could let me know if I am going
about it the wrong way.


I am creating an object database to store information about network
devices, e.g. switches and routers.

At the top level there are device objects, every device object contains
a mib object--and other various properties--where the actual data is
stored. The mib object is a dicitionary--or at least subclasses
dictionary--where the key is the oid (a unique string) and the value is
a special object called Datapoint. Datapoints come in two types Static
and Dynamic, and every Datapoint is unique.

So a simple structure looks something like this:

Device1
Mib1
{'1.3.6.1':Datapoint-x1,
'1.3.6.2':Datapoint-y1,
'1.1.5.4':Datapoint-z1,
'1.2.7.3':Datapoint-q1}

Device2
Mib2
{'1.3.6.1':Datapoint-x2,
'1.3.6.2':Datapoint-y2,
'1.1.5.4':Datapoint-z2,
'1.2.7.3':Datapoint-q2}

In the example Datapoint-xx should be read as, some unique data point in
memory.

The key in the Mib object is important because it is used by the
Datapoint is points to to look up its current value on the given device,
which is why I asked the two questions.

In my program I use snmp to look up values on network devices. i.e. 'Go
find the value of 1.3.6.1 from device1.' I want to be able to say
something like Device1.Mib['1.3.6.1].update(), and the correct Datapoint
discovers its key (oid) and parent device, then executes an snmp query
that looks something like this snmpget(keyThatPointsToSelf,
parentObj.ipAddress, parentObj.paramx)

I know of course I could keep all this in a relational database and do a
bunch of queries, but that would really suck! and I would have to track
all the Devices and oids my self. What I really want is smart objects
that think for me--thats what computers are for, right? ;)

I thought my design was a wonderfuly beautiful use of python an oop, but
perhaps I am mistaken and there is a much more pragmatic way to get the
job done. In the end preformance doesn't matter a lot. The front end
will be web based, so if the db can process faster than http/javascript
and user Bob who has to mouse, then everything will be fine.

Let me know what you think
Thanks much
--Matthew

I think that since each Datapoint appears to be unique, the simplest
thing to do is to include a reference to the parent object as an
attribute of the datapoint. Presumably when you create the Datapoint you
already know which Device and Mib it's going to be stored in, so why
make work for yourself when you can trade a little storage and make the
whole thing easy?

You might also be interested to know that the Python Software Foundation
funded the development of a Python package to support SNMP as a part of
its first round of grant funding last year, so there's at least one
other person working on this stuff!

http://www.python.org/psf/grants/

regards
Steve
 
M

Matthew Thorley

Steve said:
I think that since each Datapoint appears to be unique, the simplest
thing to do is to include a reference to the parent object as an
attribute of the datapoint. Presumably when you create the Datapoint you
already know which Device and Mib it's going to be stored in, so why
make work for yourself when you can trade a little storage and make the
whole thing easy?

I'll give that a shot and see how it goes. It makes sense, the parent
objects create the child objects, so they could very easily set the
apropriate parameter.

On the other hand, the introspecitve stuff is cool! When you say "make
more work for yourself" are you talking about 400 lines of code or 50.
Further, is there much processing required to do the magic? When python
do introspective magic, is it memory intensive? by that I mean does it
have to make copies of the objects to do the look-ups?

I don't mind copying the info like you suggest, but if the extra work
won't take more than a day or two, (or maybe even a week if its fun) I'd
like to do the introspection so that 1: I know how, 2: I can say that I
did ;)

Is there any kind of documentaion, (refference, article, blog-post,
tutorial), that explains introspection in useful detail, or at least
enough to get me started?
You might also be interested to know that the Python Software Foundation
funded the development of a Python package to support SNMP as a part of
its first round of grant funding last year, so there's at least one
other person working on this stuff!
I did see that and I was quite pleased! :) I am currently using the
authors 'old' pysnmp which gets me by, but I am very excited to try out
the new version when it is ready.


Thanks again, for the reply and for the grant to pysnmp!

-Matthew
 
S

Steve Holden

Matthew said:
Steve Holden wrote:




I'll give that a shot and see how it goes. It makes sense, the parent
objects create the child objects, so they could very easily set the
apropriate parameter.
Indeed, they will probably just need to pass "self" as an argument to
the child object's creator (it will become an argument to the __init__()
method). This will be pretty cheap, since the additional attribute will
be bound to an already-existing value.
On the other hand, the introspecitve stuff is cool! When you say "make
more work for yourself" are you talking about 400 lines of code or 50.
Further, is there much processing required to do the magic? When python
do introspective magic, is it memory intensive? by that I mean does it
have to make copies of the objects to do the look-ups?
Frankly I am not sure I see the advantage. You seem to be saying that
rather than provide each child object with a reference to its parent you
would rather provide it with a reference to the collection of parent
objects and let it work out which one it wants. Where's the benefit?
I don't mind copying the info like you suggest, but if the extra work
won't take more than a day or two, (or maybe even a week if its fun) I'd
like to do the introspection so that 1: I know how, 2: I can say that I
did ;)
Basically you'd have to iterate over the list of parent objects,
checking whether the child object's self appeared as a key in its
dictionary of children, so there's nothing really magical about it.

The *real* magic comes about when you are looking for arbitrary
references to an object, and you have to iterate over the locals() from
each stack frame, and various other magical bits and pieces.

There have been posts in the past detailing such magic, so Google will
find them for you if you are keen to bend your brain.
Is there any kind of documentaion, (refference, article, blog-post,
tutorial), that explains introspection in useful detail, or at least
enough to get me started?
Whole swathes of stuff already posted n c.l.py, not to mention Patrick
O'Brien's

http://www-106.ibm.com/developerworks/library/l-pyint.html

which has been highly spoken of.
I did see that and I was quite pleased! :) I am currently using the
authors 'old' pysnmp which gets me by, but I am very excited to try out
the new version when it is ready.


Thanks again, for the reply and for the grant to pysnmp!

-Matthew

Happy to help, but I can't take credit for the grant, since all I did as
a PSF director was vote affirmatively on the recommendations of Martin
von Lowis' extremely hard-working grants committee.

regards
Steve
 
M

Matthew Thorley

Steve said:
Indeed, they will probably just need to pass "self" as an argument to
the child object's creator (it will become an argument to the __init__()
method). This will be pretty cheap, since the additional attribute will
be bound to an already-existing value.

Frankly I am not sure I see the advantage. You seem to be saying that
rather than provide each child object with a reference to its parent you
would rather provide it with a reference to the collection of parent
objects and let it work out which one it wants. Where's the benefit?
All right then.
Happy to help, but I can't take credit for the grant, since all I did as
a PSF director was vote affirmatively on the recommendations of Martin
von Lowis' extremely hard-working grants committee.

Thanks to the PSF for the grant!

-Matthew
 
B

Bengt Richter

This may be a very rudimentary question, but here goes:

If I have a simple dictionary, where the value is a class or function,
is there an interface through which it can discover what its key is?
Similar to index() for list.

You can make a reverse dictionary, if the key:value pairs are unique and
the values are hashable. But I doubt this is the real solution to your real problem.
>>> def foo(): pass ...
>>> def bar(): pass ...
>>> dct = dict(fookey=foo, barkey=bar)
>>> dct
>>> revdict = dict((v,k) for k,v in dct.items())
>>> revdict[foo] 'fookey'
>>> revdict[bar] 'barkey'
>>> class Baz(object): pass ...
>>> dct['bazkey'] = Baz
>>> dct
>>> revdict = dict((v,k) for k,v in dct.items())
>>> revdict[Baz]
'bazkey'


But if you had

d = {'key1':foo, 'key2':foo}

What would foo's key be?
For a list, assuming I new what the parent list was I could do something
like this.
... def get_parent_index(self, parent):
... return parent.index(self)
...
a = child()
l = [a]
b = l[0]
b.get_parent_index(a)
b.get_parent_index(l)
0

Is there a way to do something like that with dicts?


On a similar note, if one object is part of another, is there a way for
the 'child' obj to discover what/who the 'parent' object is? That way
parent does not have to be explicityly passed to get_parent_index?
Any number of "parents" can refer to a given obj, so even if you
have a context where you can search successfully, you may find many "parents"
-- unless you can guarantee 1:1 as in the dct/revdict example above.
The idea is like this:

... def get_parent_index(self):
parent = self.magic_parent_discovery()
... return parent.index(self)
...
I would suggest thinking about defining a class for the graph you are concerned with
and giving it methods to add children to nodes, and automatically maintain the
parent references as you walk your graph and add or delete nodes. Then you should
easily be able to define more methods to get various info as you may want.
Properties may interest you too, giving you a way to convert plain object attributes
to dynamically computed attributes without chaninging the code that refers to the attribute.

Unless you have a huge graph, I wouldn't worry about the space. If you bump into
limitations, try __slots__ for node attributes. But if you know now that it's going
to be huge, describe your (real) problem now for better help.

Regards,
Bengt Richter
 
S

Scott David Daniels

Matthew said:
Scott David Daniels wrote: ...(explaining Python has no "the" parent)
I see what your saying, but I my situation the values of the dictionary
are unique objects created by a parent object.
But that is your convention, not Python's. Some good general rules:
1) For frequent (or fast) access you should know where something is,
rather than search for it.
2) You (your app) should be willing to "pay" for your own needs for
navigation rather than expect a built-in cost for everyone that
provides convenience for a few.
3) A very "Pythonic" storage system makes it clear how you navigate,
so relying on magic is usually a bad idea.
When the 'root object' is 'global' I see what your saying, but when

class A:
def __init__(self, container):
self.container=container

class B(dict):
def magice_get_parent(self):
...

class special_value():
def __init__(self, val):
self.val = val

def magic_get_key(self):
...

parent = A(B)
parent.container[x] = special_value(1)
parent.container[y] = special_value(2)
parent.container[z] = special_value(1)


OK, if you want help, try doing code, not sketching what it might be.
> class special_value():
Cannot be. Perhaps:
class special_value(object):
> class A:
> def __init__(self, container):
> self.container=container ....
> class B(dict): ....
> parent = A(B)
> parent.container[x] = ...

Either you must use:
parent = A(B())

or
class A:
def __init__(self, containerClass):
self.container = containerClass()

By the way, if you are subclassing dict, you might as well
use new-style throughout (so: class A(object): ...).

Now, how about rather than all of this magic, trying:

class A:
def __init__(self, container):
self.container = container
self.container.parent = self

and instead of
parent.container[x] = special_value(1)

parent.container.set(x, special_value(1))


using:
class B(dict):
...
def set(self, key, contents):
self[key] = contents
contents.origin = self, key
...

Then after:
parent = A(B())
parent.container.set(x, special_value(1))
parent.container.set(y, special_value(2))
parent.container.set(z, special_value(1))

You can do:

child = parent.container
print child.parent

value1 = parent.container[x]
box, key = value1.origin
assert box[key] is value1 and box.parent is parent

And you didn't have to use magic at all.

--Scott David Daniels
(e-mail address removed)
 
J

Jeremy Bowers

I must say I am *very* suprised that python does not have a way to look
up what key is pointing to a given object--without scanning the whole
list that is.

Assuming fairly optimal data structures, nothing is free.

Python chooses not to have bi-directional dicts built in. A good reason
for this is that it is easy to build a two-way dict out of two one-way
dicts, and there's no obvious way to build a "built-in" two-way dict that
is any more efficient than that.

Python chooses to allow all objects potentially to be dict keys, which has
overhead vs. an implementation such as that in Perl that only allows
strings. Either of those is tolerable ultimately, though I do prefer
Python's approach as I key things on objects all the time.

It's all a matter of tradeoffs. Building all the dicts as two-way in
memory consumes twice the memory and twice the processor power for a lot
of situations where the second direction isn't used, so *on average*
that's not a good tradeoff.

Even though Python doesn't have a built-in way, it is easy to write your
own class that interoperates transparently, and there are many ones you
can grab off the 'net, even given to you in this thread :)
 
T

Terry Reedy

Matthew Thorley said:
I must say I am *very* suprised that python does not have a way to look
up what key is pointing to a given object

But it does. Of course, there could be zero to many keys in any dictionary
pointing to any particular value object
--without scanning the whole list that is.

That's one way. Another is a reverse dict (for hashable values turned into
keys) with the value being a list of zero to many keys. A third (and
fastest of these) is to keep the key with the value.
Is that what list.index() does under-the-hood? I mean is
list.index(y) just the same as

itemnum = 0
for item in list:
if y == item:
return itemnum
else:
itemnum = itemnum+1

More or less, yes. If your list is sorted, you can use binary search in
the bisect module.

Terry J. Reedy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top