Comparing objects - is there a maximum object?

C

Chris Brew

I've just been writing some code to merge items from
a collection of streams, where each item has a key,
and each stream is known to be sorted in ascending
order of key. I read all the streams once, then
pick the minimum element of the results, replace
it with a new one read from the corresponding
stream, and repeat.

Thing is, what happens at end of file? I'd like to
do it by making the streams that are finished
return some object (call it endmarker) such
that min(x,endmarker) always returns x. That way,
when all the streams are returning endmarker, we
would be done. And I'd like my code to work the same
no matter what kind of thing the streams are
returning, so I want endmarker to be a generic
maximum object.

The Python documentation says:

The operators <, >, ==, >=, <=, and != compare the values of two
objects. The objects need not have the same type. If both are numbers,
they are converted to a common type. Otherwise, objects of different
types always compare unequal, and are ordered consistently but
arbitrarily

so (unless this has been superseded) it doesn't seem that there is
such an object. Any suggestions? I notice that empirically max(x,None)
seems to be always x, but again I suppose I shouldn't count on that.

Chris
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

Chris said:
so (unless this has been superseded) it doesn't seem that there is
such an object. Any suggestions?

The easiest way to produce a maximum object is

class Max:
def __cmp__(self, other):
return 1
maximum = Max()

HTH,
Martin
 
A

Andrew Dalke

Martin v. Löwis:
The easiest way to produce a maximum object is

class Max:
def __cmp__(self, other):
return 1

Shouldn't there also be a

def __rcmp__(self, other):
return -1
?

Andrew
(e-mail address removed)
 
M

Martin v. =?iso-8859-15?q?L=F6wis?=

Andrew Dalke said:
Shouldn't there also be a

def __rcmp__(self, other):
return -1
?

No, this would not be used. cmp(a,b) == -cmp(b,a)

Regards,
Martin
 
P

Peter Otten

Chris said:
Thing is, what happens at end of file? I'd like to
do it by making the streams that are finished
return some object (call it endmarker) such
that min(x,endmarker) always returns x. That way,
when all the streams are returning endmarker, we
would be done. And I'd like my code to work the same
no matter what kind of thing the streams are
returning, so I want endmarker to be a generic
maximum object.

Why not remove "streams" that have reached the end?
You could do something like

def gen(*seqs):
seqs = [iter(seq) for seq in seqs]
done = []
while True:
result = []
for it in seqs:
try:
result.append(it.next())
except StopIteration:
done.append(it)
if len(done):
for d in done:
seqs.remove(d)
done = []
if len(result) == 0:
break
yield result

# produce sample data
import random
l1 = range(5)
l2 = range(10)
l3 = range(3, 6)
for l in l1, l2, l3:
random.shuffle(l)

# demonstration
for i, x in enumerate(gen(l1, l2, l3)):
print i, x, "-->", min(x)

There may be room for improvement in the gen() function, but the general
idea is not to compare objects made up only for that purpose and when you
already know the outcome.

Peter
 
A

Andrew Dalke

Martin v. Löwis:
No, this would not be used. cmp(a,b) == -cmp(b,a)

True. Unlike + and *, cmp is communitive.

Here's the results of some instrumentation under 2.3.
.... def __getattr__(self, name):
.... print "Looking for", name
.... if name == "__cmp__":
.... return lambda other: 1
.... raise AttributeError(name)
....
data = [Max(), 0, 1, 2, 3]
data.sort()
Looking for __gt__
Looking for __coerce__
Looking for __cmp__
Looking for __gt__
Looking for __coerce__
Looking for __cmp__
Looking for __gt__
Looking for __coerce__
Looking for __cmp__
Looking for __gt__
Looking for __coerce__
Looking for __cmp__Looking for __lt__
Looking for __coerce__
Looking for __cmp__
Looking for __repr__
[0, 1, 2, 3, <__main__.Max instance at 0x013D8C88>]

Not an __rcmp__ in the mix.

Andrew
(e-mail address removed)
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top