简体   繁体   中英

Find Largest Number From Selected List Elements In Python

I am using Python 3.2.3, and would like to find the largest number from specific elements in a list. It is also important that I retain some knowledge of which element is the largest number, but am quite flexible on how this occurs. Let me explain...

Background

I have the following list:

the_list = ['Order', '1', '5', 'Order', '2', '18', 'Order', '3', '45', 'Order', '4', '2', 'Order', '5', '8', 'Order', '6', '2', 'Order', '7', '1', 'Order', '8', '1', 'Order', '9', '1']

Out of every three list elements, the first two are descriptive of the data -- ie, "Order 1", "Order 2", "Order 3" as 'Order', '1', ... 'Order', '2', ... 'Order', '3', ... all the way to "Order 9". These do not change, and provide the source or name of every third list element.

The third of every three list elements is the information in question. In this example, the numbers are 5... 18... 45... 2... and so forth. It from this every third element that I would like to find the largest number. In this case, that largest number is 45. These numbers change all the time; they could be any whole number from 0 through 100 [inclusive].

What I Have Tried So Far

I have tried using Python's max() function in two ways. First, simply...

max(the_list)

... which provides "Order" as the maximum value. A bummer on my goal.

So I decided to try making a new list, made only of every third element of the original list. Like so...

foo = (the_line[2], the_line[5], the_line[8], the_line[11], the_line[14], the_best_line[17], the_best_line[20], the_best_line[23], the_best_line[26])

max(foo)

... which provides "8" as the largest number, the 15th list element and the 5th third list element. It's a number, but isn't the highest number of 45 [in this example].

I have also dabbled in making a series of if-else statements, but was both unsuccessful and in the mind-set that there must be a more pythonic//elegant way. I admit that I may have quit too early on this route, and//or that I am in the wrong mind-set.

Something like this should work:

>>> the_list = ['Order', '1', '5', 'Order', '2', '18', 'Order', '3', '45', 'Order', '4', '2', 'Order', '5', '8', 'Order', '6', '2', 'Order', '7', '1', 'Order', '8', '1', 'Order', '9', '1']
>>> the_list[::3]
['Order', 'Order', 'Order', 'Order', 'Order', 'Order', 'Order', 'Order', 'Order']
>>> the_list[2::3]
['5', '18', '45', '2', '8', '2', '1', '1', '1']
>>> max(int(num) for num in the_list[2::3])
45

Where I've used Python's slice notation to get every third (that's the 3 ) element starting at element #2 (that's the 2 ), using the_list[2::3] .

By itself that's not enough, though, because the entries of the_list are strings and they're sorted lexicographically, not numerically. That's why I had to call int(num) on each of the terms and pass max a generator expression , here in the form '(something for elem in someseq)'.

You also say that it's important that you keep track of which element is the largest, by which I assume you mean you want the index. Given the maximum value it's easy to find which elements have it (in the general case it might not be unique, after all) using another search for elements that match it which is probably the simplest. Alternatively, you could encode the index itself into the max call:

>>> max((int(num), i) for i, num in enumerate(the_list[2::3]))
(45, 2)

which gives the max and the group-of-three index, and works because tuples are sorted by the first element, then the second, etc. This approach doesn't handle non-unique maxima as well.

To be honest, though, I'd probably start by reshaping the data kind of like @astynax did-- it doesn't feel like this list should be flat.

>>> the_list = ['Order', '1', '5', 'Order', '2', '18', 'Order', '3', '45', 'Order', '4', '2', 'Order', '5', '8', 'Order', '6', '2', 'Order', '7', '1', 'Order', '8', '1', 'Order', '9', '1']
>>> items = zip(*[iter(the_list)] * 3)
>>> items
[('Order', '1', '5'), ('Order', '2', '18'), ('Order', '3', '45'), ('Order', '4', '2'),('Order', '5', '8'), ('Order', '6', '2'), ('Order', '7', '1'), ('Order', '8', '1'), ('Order', '9', '1')]    
>>> max(items, key=lambda x: int(x[2]))
('Order', '3', '45')
   >>> the_list = ['Order', '1', '5', 'Order', '2', '18', 'Order', '3', '45', 'Order', '4', '2', 'Order', '5', '8', 'Order', '6', '2', 'Order', '7', '1', 'Order', '8', '1', 'Order', '9', '1']
   >>> max(map(int,the_list[2::3]))
    45

here 3 in [2::3] represent step , ie after '5' it jumps to '18' and then to '45', and so on, taking a jump of 3 every time. The default value of step is 1 if not provided. So,

>>> the_list[2::3]
['5', '18', '45', '2', '8', '2', '1', '1', '1']

map() is a function which applies a particular function to every object of an iterable, which in this case is the_list[2::3] and the function applied is int . map() returns a list in python 2.x and map object in python 3.x.

您可以尝试类似

my_max = max( [the_list[i] for i in range(len(the_list)) if (i+1)%3==0 ] )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM