[Tutor] Implementation of list comparison operators, was Re: Doubt in Python
Peter Otten
__peter__ at web.de
Thu Jan 17 10:34:27 EST 2019
Alan Gauld via Tutor wrote:
> On 17/01/2019 07:24, Maninath sahoo wrote:
> >>>> a=[100,50,30]
> >>>> b=[100,90,3]
> >>>> a<b
> > True
> >>>> a>b
> > False
> >
> >
>> How it compares between two lists
>>
> The algorithm is probably described somewhere in the documentation
> but my understanding is that it looks something like this(in pdeudo code):
> def isGreater(X,Y):
>
> if len(X) <= len(Y) return False
>
> if X[0] < Y[0] return False
>
> if X[0] == Y[0] return X[1:] > Y[1:]
>
> return True
>
>
> And similarly for the other operators.
>
> But that's just based on playing with the interpreter and exploring
> different values...
>>> [10] > [1, 2, 3]
True
>>> [1] > [10, 2, 3]
False
So you cannot decide on length alone.
My analogy of list comparison would be words in a dictionary; you compare
individual letters until you reach a decision:
mad <--> mad
m -> equal
a -> equal
d -> equal
(no character on both sides) --> mad == mad
madam <--> mad
m -> equal
a -> equal
d -> equal
a is greater than (no character) --> madam > mad
madam <--> man
m -> equal
a -> equal
d is less than n --> madam < man
A tentative implementation of less() (untested):
# zip() intentionally omitted
def less(x, y):
for i in range(min(len(x), len(y))):
if not x[i] == y[i]:
return x[i] < y[i]
return len(x) < len(y)
Finally here's a tool that wraps all comparison operations of the list
items.
$ cat track_compare.py
class A:
def __init__(self, value):
self.value = value
def __lt__(self, other):
print(self, "<?", other)
return self.value < other.value
def __eq__(self, other):
print(self, "==?", other)
return self.value == other.value
def __gt__(self, other):
print(self, ">?", other)
return self.value > other.value
def __le__(self, other):
print(self, "<=?", other)
return self.value <= other.value
def __ge__(self, other):
print(self, ">=?", other)
return self.value >= other.value
def __ne__(self, other):
print(self, "!=?", other)
return self.value != other.value
def __repr__(self):
return repr(self.value)
def noisy(items):
return [A(item) for item in items]
a = noisy([1, 2, 3])
b = noisy([1, 10, 20])
c = noisy([1])
d = noisy([1])
print("{} < {}".format(a, b))
a < b
print("\n{} != {}".format(c, d))
c != d
print("\n{} == {}".format(c, d))
c == d
$ python3 track_compare.py
[1, 2, 3] < [1, 10, 20]
1 ==? 1
2 ==? 10
2 <? 10
[1] != [1]
1 ==? 1
[1] == [1]
1 ==? 1
$
I tried to instrument the list.__len__() method in a similar way, but the
list's comparison methods do not use that overriden method.
More information about the Tutor
mailing list