TypeError: unorderable types: tuple() < int() in Python 3

10,156

Solution 1

It is happening because you are comparing int and a tuple. In python2x, default cmp operation was defined for different inbuilt objects, which has been removed in python3.

Python 3 ignores the cmp() method. In addition to this, the cmp() function is gone! This typically results in your converted code raising a TypeError: unorderable types error. So you need to replace the cmp() method with rich comparison methods instead. To support sorting you only need to implement lt(), the method used for the “less then” operator, <.

Official documentation

So, in python2, we can do something like this

(2, 3) > 2

but it raises TypeError in python3. If this code was working in python2, then most probably it was bug that was implicitly being handled by default comparison behaviour.

Now in your example:-

#value of scores that are being compared for sorting
scores = [(0, (1, (11, 8, 7, 6, 2))), (1, (1, (12, 5, 3, 1, 0))), (2, ((2, 2, 1), (12, 6, 7))), (3, (1, (11, 8, 6, 5, 3)))]

print(type(scores[1][1][0])) # <class 'int'>
print(type(scores[2][1][0])) # <class 'tuple'>

which as I have explained does not work in python3. What is the criteria you are assuming for comparing a tuple and an int.

If you really want to compare different type of objects, then you need to roll out your own version of tuple, and use that object in your scores instead.

class MyTuple(tuple):

     def __lt__(self, other):
        pass

Default tuple comparison python 2

Note:- I don't recommend using this approach. It was just for instructional purposes.

Solution 2

The solution: Convert the integer into a tuple: score = ([(1, ), (3,1,1,1)], [(3,1,1,2), (5,)])[flush][straight]

Share:
10,156
Nickpick
Author by

Nickpick

Pokerbots, neural networks, artificial intelligence, kite surfing, piano playing

Updated on June 15, 2022

Comments

  • Nickpick
    Nickpick almost 2 years

    The below code is ordering poker hands. It works well in Python 2.7 but it does not work in Python 3. What are the changes that have been made causing it to give an TypeError: unorderable types: tuple() < int()?

    def poker(hands):
        scores = [(i, score(hand.split())) for i, hand in enumerate(hands)]
        winner = sorted(scores , key=lambda x:x[1])[-1][0]
        return hands[winner]
    
    def score(hand):
        ranks = '23456789TJQKA'
        rcounts = {ranks.find(r): ''.join(hand).count(r) for r, _ in hand}.items()
        score, ranks = zip(*sorted((cnt, rank) for rank, cnt in rcounts)[::-1])
        if len(score) == 5:
            if ranks[0:2] == (12, 3): #adjust if 5 high straight
                ranks = (3, 2, 1, 0, -1)
            straight = ranks[0] - ranks[4] == 4
            flush = len({suit for _, suit in hand}) == 1
            '''no pair, straight, flush, or straight flush'''
            score = ([1, (3,1,1,1)], [(3,1,1,2), (5,)])[flush][straight]
        return score, ranks
    
     >>> poker(['8C TS KC 9H 4S', '7D 2S 5D 3S AC', '8C AD 8D AC 9C', '7C 5H 8D TD KS'])
     '8C AD 8D AC 9C'