Re: Elegant compare
On Sat, 10 Aug 2013 21:41:00 -0600, Jason Friedman wrote: class my_class: def __init__(self, attr1, attr2): self.attr1 = attr1 #string self.attr2 = attr2 #string def __lt__(self, other): if self.attr1 other.attr1: return True else: return self.attr2 other.attr2 I will run into problems if attr1 or attr2 is None, and they legitimately can be. I know I can check for attr1 or attr2 or both being None and react accordingly, but my real class has ten attributes and that approach will be long. What are my alternatives? This is a hard question to answer, because your code snippet isn't clearly extensible to the case where you have ten attributes. What's the rule for combining them? If instance A has five attributes less than those of instance B, and five attributes greater than those of instance B, which wins? But if I had to guess an approach, I'd start with a helper function (or method) that compares two raw values: def compare(a, b): Return -ve for less than, 0 for equal, +ve for greater than. if a is None: return 0 if b is None else -1 if b is None: return 1 return (b a) - (a b) Now, in your class, you can use this helper function to check each attribute in turn. Assuming that if an attribute is equal, you move on to check the next one: class MyClass: def _compare(self, other): for attr in 'attr1 attr2 attr3 attr4'.split(): a, b = getattr(self, attr), getattr(other, attr) triflag = compare(a, b) if triflag: return triflag return 0 def __lt__(self, other): if not isinstance(other, MyClass): return NotImplemented return self._compare(other) 0 def __eq__(self, other): if not isinstance(other, MyClass): return NotImplemented return not self._compare(other) def __ne__(self, other): if not isinstance(other, MyClass): return NotImplemented return bool(self._compare(other)) and so on. You can save a certain amount of repetition (by my count, six lines of code) by pulling out the if not isinstance check into a decorator, but since the decorator is likely to be about six lines long, I wouldn't bother :-) -- Steven -- http://mail.python.org/mailman/listinfo/python-list
Re: Elegant compare
This is a hard question to answer, because your code snippet isn't clearly extensible to the case where you have ten attributes. What's the rule for combining them? If instance A has five attributes less than those of instance B, and five attributes greater than those of instance B, which wins? Yes, my code snippet was too short, I should have said: class my_class: def __init__(self, attr1, attr2, attr3): self.attr1 = attr1 #string self.attr2 = attr2 #string self.attr3 = attr3 #string def __lt__(self, other): if self.attr1 other.attr1: return True elif self.attr2 other.attr2: return True else: return self.attr3 other.attr3 Chris's answer is actually perfectly adequate for my needs. Thank you Steve and Chris. -- http://mail.python.org/mailman/listinfo/python-list
Elegant compare
class my_class: def __init__(self, attr1, attr2): self.attr1 = attr1 #string self.attr2 = attr2 #string def __lt__(self, other): if self.attr1 other.attr1: return True else: return self.attr2 other.attr2 I will run into problems if attr1 or attr2 is None, and they legitimately can be. I know I can check for attr1 or attr2 or both being None and react accordingly, but my real class has ten attributes and that approach will be long. What are my alternatives? -- http://mail.python.org/mailman/listinfo/python-list
Re: Elegant compare
On Sun, Aug 11, 2013 at 4:41 AM, Jason Friedman jsf80...@gmail.com wrote: class my_class: def __init__(self, attr1, attr2): self.attr1 = attr1 #string self.attr2 = attr2 #string def __lt__(self, other): if self.attr1 other.attr1: return True else: return self.attr2 other.attr2 I will run into problems if attr1 or attr2 is None, and they legitimately can be. I know I can check for attr1 or attr2 or both being None and react accordingly, but my real class has ten attributes and that approach will be long. What are my alternatives? The first question is: What should the comparison do with a None value? Should it be considered less than every string? If so, you could simply use: if (self.attr1 or ) (other.attr1 or ): which will treat any falsy value as blank. ChrisA -- http://mail.python.org/mailman/listinfo/python-list