accessing an object instance by only having one of its attribute values

F

feli.hp

Hello all,

Imaybe someone can help me with this question.
Is there a direct way of accessing an object instance, if all I know
is the value of one of its attributes?
The object is part of a list of objects, and I would like to pick the
object directly by using this attribute value, instead of going
through the list and checking if each objects attribute value is the
one I am looking for.

Thank you in advance
 
S

Stargaming

Hello all,

Imaybe someone can help me with this question.
Is there a direct way of accessing an object instance, if all I know
is the value of one of its attributes?
The object is part of a list of objects, and I would like to pick the
object directly by using this attribute value, instead of going
through the list and checking if each objects attribute value is the
one I am looking for.

Thank you in advance

Okay, imagine you got a bunch of small packets (presents or something
similiar). You want to get rid of the lightest one. You cannot see
weights, so, what you're doing is basically measuring the weight of
*every single packet*, compare and pick. No way around.

There might be some ways not having to touch *each* object, if you
precompute some results. So, in the example above, you could divide the
packets into two categories, "more than 50 lbs" and "less than 50 lbs",
for example. I think binary trees might be interesting here but touching
every object would be way easier.

HTH,
Stargaming
 
M

mshiltonj

Hello all,

Imaybe someone can help me with this question.
Is there a direct way of accessing an object instance, if all I know
is the value of one of its attributes?
The object is part of a list of objects, and I would like to pick the
object directly by using this attribute value, instead of going
through the list and checking if each objects attribute value is the
one I am looking for.

Thank you in advance


I'd set up a dict as a lookup table, assuming the attribute values are
unique per object.


list_of_objects = (obj1, obj2, obj3, obj4);

obj_lookup_by_attr = {};

for obj in list_of_objects:
obj_lookup_by_attr.set(obj.attr, obj)

[...]

obj = obj_lookup_by_attr.get(attr_val, None);

if (obj):
[...]
 
P

Paul McGuire

Hello all,
Imaybe someone can help me with this question.
Is there a direct way of accessing an object instance, if all I know
is the value of one of its attributes?
The object is part of a list of objects, and I would like to pick the
object directly by using this attribute value, instead of going
through the list and checking if each objects attribute value is the
one I am looking for.
Thank you in advance

I'd set up a dict as a lookup table, assuming the attribute values are
unique per object.

list_of_objects = (obj1, obj2, obj3, obj4);

obj_lookup_by_attr = {};

for obj in list_of_objects:
obj_lookup_by_attr.set(obj.attr, obj)

[...]

obj = obj_lookup_by_attr.get(attr_val, None);

if (obj):
[...]

I have some comments on the Pythonicity of your suggestions. Same
assumption, object attr is a unique key of some sort. How to create
the dict of objects, and how to retrieve an object by key.

-- Paul


list_of_objects = (obj1, obj2, obj3, obj4);

# creating a dict by initializing to empty, and then looping
# through input list and adding items one at a time
obj_lookup_by_attr = {};
for obj in list_of_objects:
#obj_lookup_by_attr.set(obj.attr, obj)
# why use set for this? why not just this:
obj_lookup_by_attr[obj.attr] = obj

# or even better might be to use a generator expression to create a
# sequence of tuples, and call the dict constructor - a good idiom to
# learn
obj_lookup_by_attr = dict( (obj.attr,obj) for obj in list_of_objects )

[...]

obj = obj_lookup_by_attr.get(attr_val, None);

# oh woe if obj is an instance of a class that defines special
# true/falseness - obj might be a real object, but evaluates to false
#
#if (obj):
#
# much better to test this way
# (and NEVER test using "if obj != None:" - this is wasteful
# nonsense, since None is a singleton)
if obj is not None:
[...]
 
M

mshiltonj

On Jul 8, 2:11 pm, mshiltonj <[email protected]> wrote:
I have some comments on the Pythonicity of your suggestions. Same
assumption, object attr is a unique key of some sort. How to create
the dict of objects, and how to retrieve an object by key.

-- Paul

I was probably being overly helpful, in a bad way. I'm new to python,
I'm not very pythonic yet, and still learning the python idioms.

Not sure why I slipped into the habit of testing for None, though. :-(

Probably a perl thing, where I'm regularly testing for defined-ness.
"if ($foo)" is different than "if (defined $foo)"

Still, I'm really like python so far.
 
P

Paul McGuire

Not sure why I slipped into the habit of testing for None, though. :-(

There is nothing wrong with testing for None. But the right ways to
test for None are:
if x is None:
and
if x is not None:

Since None is a singleton, it is a waste to test using == or !=. The
identity tests 'is' and 'is not' are sufficient.

In fact, testing for None is a very common way to implement a default
argument for an instance method (usually __init__ of a class) in which
the default is a list (usually an empty list, but not always).

The WRONG way:

class BorkBorkBork(object):
def __init__(self,words=[]):
self.vocabulary = words

Since the argument "words=[]" gets evaluated at class definition time,
all instances of BorkBorkBork will end up using the same list, which
is almost never the desired behavior, and a common surprise for new
Pythoners.

The ALMOST RIGHT way:

class BorkBorkBork(object):
def __init__(self,words=None):
if words:
self.vocabulary = words
else:
self.vocabulary = []

This is ALMOST RIGHT, now the default value of words is None, and the
if test fails. Unfortunately, if this were called using:

chef = BorkBorkBork([])

then the if test fails, not because the argument was omitted from the
constructor, but BECAUSE THE PASSED VALUE EVALUATES TO FALSE! "So
what?" you say, since in the else branch we just set the default value
to an empty list anyway. But what about this?

Why the ALMOST RIGHT way isn't ALWAYS RIGHT:

class BorkBorkBork(object):
def __init__(self,words=None):
if words:
self.vocabulary = words
else:
self.vocabulary = ['bork','hernie','fernie','bernie']

Our default starting vocabulary isn't empty now, but there is no way
to initialize a BorkBorkBork'er to an empty list.

The RIGHT way:

class BorkBorkBork(object):
def __init__(self,words=None):
if words is not None:
self.vocabulary = words
else:
self.vocabulary = ['bork','hernie','fernie','bernie']


Now the loophole is closed. If we want to initialize to an empty
list, we can do so; or if we omit the argument, then the newly-
constructed BorkBorkBork instance will have a minimally functional
vocabulary.

So testing for None is not inherently bad, and in many cases a healthy
idiom.

-- Paul
 
B

Bruno Desthuilliers

mshiltonj a écrit :
I was probably being overly helpful, in a bad way. I'm new to python,
I'm not very pythonic yet, and still learning the python idioms.

Not sure why I slipped into the habit of testing for None, though. :-(

Probably a perl thing, where I'm regularly testing for defined-ness.
"if ($foo)" is different than "if (defined $foo)"

I'm not sure about the exact meaning of "defined-ness" in Perl, but in
Python, trying to access a non-existing name - which is not the same
thing as a name bound to None - will raise a NameError.

And while we're at it, you definitively don't need the parens around the
test.
 

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
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top