12

The Python documentation states that, when called with more than one argument, max() returns the largest of the arguments.

>>> a = (1, 1, 1, 9)
>>> b = (4, 5, 6)
>>> max(a, b)
(4, 5, 6)

What defines how large a tuple, in this context, is? The tuple a has both a higher number of elements (four versus three) and its maximum value (9) is greater than the maximum number that can be found in b (6), so by any criteria I would have expected it to be the returned one. How are the tuples being compared by max()?

plok
  • 705
  • 7
  • 30
  • 1
    If you want the longest tuple, use `max(a, b, key=len)`. For the tuple with the largest number in it use `max(a, b, key=max)` – John La Rooy Mar 06 '12 at 00:27

4 Answers4

13

Tuples like all other sequences are ordered lexicographically: the order of two tuples is decided by the first position where the tuples differ. Quoting from python reference:

Tuples and lists are compared lexicographically using comparison of corresponding elements.

Your two tuples differ on the first position and since 4 > 1, we have

>>> (4, 5, 6) > (1, 1, 1, 9)
True
Adam Zalcman
  • 26,643
  • 4
  • 71
  • 92
  • Is inter-type comparison documented somewhere? I'm looking for an explanation on why "python" > [130, 129] equals to True, or why [1, 2, 3] > 999 returns also True. – plok Mar 07 '12 at 22:06
  • 1
    The ordering of values of different types is arbitrary, so one should not rely on it. See the reference I gave. One more quote: "Otherwise, objects of different types always compare unequal, and are ordered consistently but arbitrarily." – Adam Zalcman Mar 07 '12 at 22:21
  • 1
    See also, [this question](http://stackoverflow.com/questions/3270680/how-does-python-compare-string-and-int). – Adam Zalcman Mar 07 '12 at 22:21
4

From left to right it compares each element of the tuples until it finds one larger than the other. This tuple is then returned. For example

>>> a = (2,0,0,0)
>>> b= (1,1,1,1)
>>> max(a,b)
(2, 0, 0, 0)

>>> b = (2,1,1,1)
>>> max(a,b)
(2, 1, 1, 1)

After an element is found in one tuple that is larger than the respective element in the other the remaining values have no effect on which tuple is returned.

MDT
  • 461
  • 6
  • 10
  • I came too the same conclusion through trial and error, But it doesn't seem to be documented anywhere I looked, got any idea where it may be? – 8bitwide Mar 06 '12 at 00:12
  • Nope, I'm suprised how vague the documentation for max() is really. – MDT Mar 06 '12 at 00:15
3

They are compared one element at a time, much like any other sequence. It's(probably) easiest to understand if you compare it with string comparison:

>>> (1, 2, 3) > (1, 2, 4)
False
>>> (2, 2, 3) > (1, 2, 4)
True
>>> 'abc' > 'abd'
False
>>> 'bbc' > 'abd'
True
stranac
  • 26,638
  • 5
  • 25
  • 30
0

Comparison using < should be roughly equivalent to:

def compare(a,b):
    print ""
    print "testing %s < %s" %(str(a),str(b))
    for ai,bi in zip(a,b):
        print "comparing elements",ai,bi
        if ai < bi:
            return True
        if bi < ai:
            return False
    if len(a)<len(b):
        return True
    return False

test_cases = [tuple([1]),(1,2),(1,1),(1,1,1),(None,None,None),tuple([None]),(99,99)]

print "running tests"
for a in test_cases:
    for b in test_cases:
        assert(compare(a,b) == (a<b))
"""
>>>
running tests

testing (1,) < (1,)
comparing elements 1 1

testing (1,) < (1, 2)
comparing elements 1 1

testing (1,) < (1, 1)
comparing elements 1 1

testing (1,) < (1, 1, 1)
comparing elements 1 1

testing (1,) < (None, None, None)
comparing elements 1 None

testing (1,) < (None,)
comparing elements 1 None

testing (1,) < (99, 99)
comparing elements 1 99

testing (1, 2) < (1,)
comparing elements 1 1

testing (1, 2) < (1, 2)
comparing elements 1 1
comparing elements 2 2

testing (1, 2) < (1, 1)
comparing elements 1 1
comparing elements 2 1

testing (1, 2) < (1, 1, 1)
comparing elements 1 1
comparing elements 2 1

testing (1, 2) < (None, None, None)
comparing elements 1 None

testing (1, 2) < (None,)
comparing elements 1 None

testing (1, 2) < (99, 99)
comparing elements 1 99

testing (1, 1) < (1,)
comparing elements 1 1

testing (1, 1) < (1, 2)
comparing elements 1 1
comparing elements 1 2

testing (1, 1) < (1, 1)
comparing elements 1 1
comparing elements 1 1

testing (1, 1) < (1, 1, 1)
comparing elements 1 1
comparing elements 1 1

testing (1, 1) < (None, None, None)
comparing elements 1 None

testing (1, 1) < (None,)
comparing elements 1 None

testing (1, 1) < (99, 99)
comparing elements 1 99

testing (1, 1, 1) < (1,)
comparing elements 1 1

testing (1, 1, 1) < (1, 2)
comparing elements 1 1
comparing elements 1 2

testing (1, 1, 1) < (1, 1)
comparing elements 1 1
comparing elements 1 1

testing (1, 1, 1) < (1, 1, 1)
comparing elements 1 1
comparing elements 1 1
comparing elements 1 1

testing (1, 1, 1) < (None, None, None)
comparing elements 1 None

testing (1, 1, 1) < (None,)
comparing elements 1 None

testing (1, 1, 1) < (99, 99)
comparing elements 1 99

testing (None, None, None) < (1,)
comparing elements None 1

testing (None, None, None) < (1, 2)
comparing elements None 1

testing (None, None, None) < (1, 1)
comparing elements None 1

testing (None, None, None) < (1, 1, 1)
comparing elements None 1

testing (None, None, None) < (None, None, None)
comparing elements None None
comparing elements None None
comparing elements None None

testing (None, None, None) < (None,)
comparing elements None None

testing (None, None, None) < (99, 99)
comparing elements None 99

testing (None,) < (1,)
comparing elements None 1

testing (None,) < (1, 2)
comparing elements None 1

testing (None,) < (1, 1)
comparing elements None 1

testing (None,) < (1, 1, 1)
comparing elements None 1

testing (None,) < (None, None, None)
comparing elements None None

testing (None,) < (None,)
comparing elements None None

testing (None,) < (99, 99)
comparing elements None 99

testing (99, 99) < (1,)
comparing elements 99 1

testing (99, 99) < (1, 2)
comparing elements 99 1

testing (99, 99) < (1, 1)
comparing elements 99 1

testing (99, 99) < (1, 1, 1)
comparing elements 99 1

testing (99, 99) < (None, None, None)
comparing elements 99 None

testing (99, 99) < (None,)
comparing elements 99 None

testing (99, 99) < (99, 99)
comparing elements 99 99
comparing elements 99 99"""
Rusty Rob
  • 16,489
  • 8
  • 100
  • 116