-4

When i run the following

def max(L):
    m = L[0][0]
    for item in L:
        if item[0] > m:
            m = item
    return m

L = [[20, 10], [10, 20], [30, 20],[12,16]]
print(max(L))

i get the error TypeError: unorderable types: int() > list() at line 4. The confusion comes when i try to get the len() of both members. So from the error message it's reasonable to assume m is the list so i run

def max(L):
    m = L[0][0]
    for item in L:
        len(m)
        if item[0] > m:
            m = item
    return m

L = [[20, 10], [10, 20], [30, 20],[12,16]]
print(max(L))

and get the error len(m) TypeError: object of type 'int' has no len(). Ok so the only option left is that item[0] is the list... so similarly

def max(L):
    m = L[0][0]
    for item in L:
        len(item[0])
        if item[0] > m:
            m = item
    return m

L = [[20, 10], [10, 20], [30, 20],[12,16]]
print(max(L))

and i get the same error: len(item[0]) TypeError: object of type 'int' has no len(). Since I'm somewhat certain you can compare 2 ints, I have a hard time understanding what to do about the error originally stated.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
xor
  • 25
  • 6
  • 4
    What do you think `len(m)` does? It calculates the length of the list... which you then *ignore completely*. – jonrsharpe Sep 16 '16 at 15:28
  • ?.... its just meant to see if i get an error as it doesn't work with number data types thus providing the confusion as to why i get error when the compiler states that there exists 1 in the comparison – xor Sep 16 '16 at 15:32
  • Python has an efficient built-in `max` function, there's no need to write your own. But if you want to write your own for learning purposes it's a good idea to give it a different name. – PM 2Ring Sep 16 '16 at 15:33
  • What are you expecting from `item[0] > m`? One thing is a list, the other is an integer. The error messages you've given are all consistent with that. What result should the comparison give? *"I'm somewhat certain you can compare 2 ints"* - yeah, but that's not what you're doing. – jonrsharpe Sep 16 '16 at 15:34
  • You didn't tell us what you expect your code to do. Do you just want to find the sublist in `L` with the greatest first element? – PM 2Ring Sep 16 '16 at 15:34
  • alright, will do. The reason for making the function was to get the max of all left elements of ordered pair `(x,y)` – xor Sep 16 '16 at 15:36
  • again the confusion follows from the assumption that when the compiler states `len(m) TypeError: object of type 'int' has no len()` the object `m` is an `int` and the same error message is shown for the object `item[0]` therefore making `item[0]` (under this assumption) an `int` and since you should be able to compare `ints` I'm confused as to why the original error message makes sense – xor Sep 16 '16 at 15:41

2 Answers2

2

In the first iteration of your for loop, doing m = item makes m reference a list which afterwards cannot be compared with an int (viz. item[0] > m) in the next iteration.

You should instead assign m to one of the elements in item, say m = item[0] (to find maximum from first element in each sublist), depending on how exactly you want to compute your maximum value.

On a lighter note, if you're looking for a global maximum, you could simply flatten the list and make this easier.

Community
  • 1
  • 1
Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139
0

As Moses Koledoye says, you are getting that TypeError: unorderable types: int() > list() error because the first assignment in the loop assigns the whole item to m, so the next time you attempt to compare you're comparing the list m with the integer item[0]. So you just need to assign item[0] to m. Like this:

def max0(L):
    m = L[0][0]
    for item in L:
        if item[0] > m:
            m = item[0]
    return m

L = [[20, 10], [10, 20], [30, 20], [12, 16]]
print(max0(L))

output

30

But there's a better way to do this: use the built-in max with a key function that grabs the first element from each list in the sequence you pass to `max.

from operator import itemgetter

L = [[20, 10], [10, 20], [30, 20], [12, 16]]
m = max(L, key=itemgetter(0))
print(m)

output

[30, 20]

You can also do this with a simple lambda function, rather than importing itemgetter, but itemgetter is more efficient.

m = max(L, key=lambda u:u[0])

In fact, you don't really need to supply a key function here because Python will happily compare 2 lists (or tuples). It compares the corresponding elements in the two lists, stopping as soon as it finds a pair of elements that are unequal. So [30, 20] > [30, 19] evaluates to True, and so does [30, 20] > [29, 1000]. The 2 lists don't have to be the same length; [30, 20, 0] > [30, 20] evaluates to True.

So you could just do

m = max(L)

but using itemgetter is better (and probably more efficient) because it explicitly says to only compare the sublists by their first element.

PM 2Ring
  • 54,345
  • 6
  • 82
  • 182