-1

When working with namedtuples, it seems there is a default "value" for the object allowing one to compare two named tuples with the < > operators. Can anyone explain where this value comes from or why this code returns True? is there a clever way to make the > operator compare the age without using Person.age?

>>>from collections import namedtuple
>>>Person = namedtuple('Person', ['age', 'name'])
>>>bob = Person('20', 'bob')
>>>jim = Person('20', 'jim')
>>>bob < jim
True
wolfgee91
  • 13
  • 6
  • 2
    `namedtuple` objects *are `tuple` objects*. Tuples are compared lexicographically. – juanpa.arrivillaga Dec 22 '17 at 21:21
  • I believe from `('20', 'bob') < ('20', 'jim')`, you can see the corresponding elements in the tuples are lexicographically compared. – Abdou Dec 22 '17 at 21:21
  • 1
    @roganjosh yeah, but that seems like it should simply be another question, and regardless, how to implement comparisons in Python is *also* a duplicate. Feel free to vote to re-open. It's a democracy in that regard. – juanpa.arrivillaga Dec 22 '17 at 21:25

2 Answers2

3

You could do something like this:

from collections import namedtuple

class Person(namedtuple('Person', ['age', 'name'])):
    def __gt__(self, other):
        return self.age > other.age

    def __lt__(self, other):
        return self.age < other.age

    def __eq__(self, other):
        return self.age == other.age

However, does it really make sense for a Person to be less than or greater than by age? Why not explicitly check Person.age?

Galen
  • 1,307
  • 8
  • 15
  • 1
    I advise against this, generally, a subclass should behave like it's super class, i.e. it is a specialization, but any property of the parent class should also hold for the child class. In this case, the child-class is behaving differently for comparisons. Probably just better to make an entirely separate classs that doesn't derive from `namedtuple`, or as you say, just be explicit and compare the ages... – juanpa.arrivillaga Dec 22 '17 at 21:24
0

Seems like it's using string comparison, just concatenating the values:

>>> Person = namedtuple('Person', ['age', 'name'])
>>> bob = Person('20', 'bob')
>>> jim = Person('20', 'jim')
>>> bob < jim
True
>>> bob = Person('20', 'jin')
>>> bob < jim
False
>>> bob = Person('20', 'jim')
>>> bob < jim
False
>>> bob = Person('21', 'jim')
>>> bob < jim
False
>>> bob = Person('19', 'jim')
>>> bob < jim
True
lynxlynxlynx
  • 1,371
  • 17
  • 26