Here is a simple, understandable, dynamic procedural way around this:
class Object: def __init__(self, somelist): self.classification = somelist[0] # String self.type = somelist[1] # String self.first = somelist[2] # Integer self.last = somelist[3] # Integer def weight(self): return self.last - self.first def __str__(self): return "Object(%r, %r, %r, %r)" % (self.classification, self.type, self.first, self.last) __repr__ = __str__ obj1 = Object(['A', 'x', 4, 17]) obj2 = Object(['A', 'y', 5, 20]) obj3 = Object(['B', 'z', 10, 27]) obj4 = Object(['B', 'z', 2, 15]) obj5 = Object(['B', 'z', 20, 40]) obj6 = Object(['A', 'x', 6, 10]) obj7 = Object(['A', 'x', 2, 9]) olist = [obj1, obj2, obj3, obj4, obj5, obj6, obj7] mindict = {} for o in olist: key = (o.classification, o.type) if key in mindict: if o.weight() >= mindict[key].weight(): continue mindict[key] = o from pprint import pprint pprint(mindict)
and here is the conclusion:
{('A', 'x'): Object('A', 'x', 6, 10), ('A', 'y'): Object('A', 'y', 5, 20), ('B', 'z'): Object('B', 'z', 2, 15)}
Note: __str__ , __repr__ and pprint are only for getting a fancy printout, this is not necessary. Also the above code works unchanged in Python 2.2 to 2.7.
Runtime : O (N), where N is the number of objects in the list. Object sorting solutions are O (N * log (N)) on average. Another solution is O (K * N), where K <= N is the number of unique (classification, type) keys obtained from objects.
Used additional memory : only O (K). Other solutions are O (N).