5

If I have a list of strings such as ["A", "B", "1", "0", "C", "2"], how can I have Python elegantly grab the "highest" value (2) of that list?

For example, if the list above were to be sorted from lowest to highest, it would be

[A, B, C, 0, 1, 2]

and I would need to grab 2.

using sorted(), organises the list in the following way

[0, 1, 2, A, B, C]
grg
  • 5,023
  • 3
  • 34
  • 50
user3158105
  • 51
  • 1
  • 2

5 Answers5

7

You could provide a custom key to sorted that causes nondigit characters to appear before digits:

>>> x = ["A", "B", "1", "0", "C", "2"]
>>> sorted(x, key = lambda item: (item.isdigit(), item))
['A', 'B', 'C', '0', '1', '2']
>>> max(x, key = lambda item: (item.isdigit(), item))
'2'

A more general solution could be to explicitly specify the kind of ordering you want. This makes it easy to change the implementation if you change your mind on what is "highest".

>>> ordering = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
>>> x = ["A", "B", "1", "0", "C", "2"]
>>> print max(x, key=ordering.index)
2

>>> #Actually, I've decided that A should be highest!
>>> ordering = "BCDEFGHIJKLMNOPQRSTUVWXYZ0123456789A"
>>> print max(x, key=ordering.index)
A

This may be a little slower than the first solution, since index runs in linear time, but you may find the tradeoff worthwhile if you feel it makes the code more understandable.

Kevin
  • 74,910
  • 12
  • 133
  • 166
  • Might as well replace `sorted` by `max` then, if you want the highest value - there's no need to sort in that case, which improves time complexity. – Thijs van Dien Jan 03 '14 at 17:50
  • That's a great idea for a custom ordering scheme! I'm stealing that for my own bag of tricks, thanks! – Adam Smith Jan 03 '14 at 17:56
  • 1
    `ordering = {k: v for v, k in enumerate("BCDEFGHIJKLMNOPQRSTUVWXYZ0123456789A")}` with `key=ordering.get` and it's no longer slower. Or for whom likes it that way: `ordering = dict(zip("BCDEFGHIJKLMNOPQRSTUVWXYZ0123456789A", itertools.count()))`. Yet I agree that your version is easier to grasp. – Thijs van Dien Jan 03 '14 at 18:25
  • @Kevin, This is perfect. Simple and Flexible. Thanks! – user3158105 Jan 03 '14 at 20:01
0
my_list = ["A", "B", "1", "0", "C", "2"]
my_list.sort()
print(my_list[-1])

However, this will print "C". Letters are "greater than" numbers in ASCII

Do you want to consider numbers 'higher than' letters?

Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
0
a = ["A", "B", "1", "0", "C", "2"]
max([x for x in a if x.isdigit()])
C.B.
  • 8,096
  • 5
  • 20
  • 34
  • 1
    This works for the sample input given by the OP, but what if he gives it a list that has no digits at all? – Kevin Jan 03 '14 at 17:42
  • 1
    @Kevin yeah would need details of how the list is constructed and expected data. – C.B. Jan 03 '14 at 17:43
0

This iterates over the list and sets the value of max to the the value of each if each is anumber and greater than the current value of max:

max = 0
for item in lst:
    if not item.isalpha():
        if int(item) > max:
            max = int(item)
        else:
            pass

print(max)
kylieCatt
  • 10,672
  • 5
  • 43
  • 51
  • 1
    Calling the variable `each` is very confusing. For example, `each.isalpha()` suggests that it refers to all elements in the list, yet it refers to just a single one... Rather call it `item` or `element`. – Thijs van Dien Jan 03 '14 at 17:44
0

If your goal is to get the largest number among the elements of your list, you could try casting the numbers to integers and then finding the maximum.

def casted_max(l):
    casted = [int(m) for m in l if m.isdigit()]
    if casted:
        return max(casted)
    else:
        return -1
Daniel
  • 695
  • 7
  • 20