anfield
anfield

Reputation: 333

Max in position x in list of lists

How do I get the max value in position x in a list of lists, and return that along with the data in position 0? A sample of my current list is pasted below. I was considering making another list which contains the elements i want then sorting that one, but I am guessing there is a better to do this

Data currently being output

[['Name1', '1 (5)', '0', '0', '0', 'TeamPos', 'TeamA'], 
 ['Name2', '13 (0)', '5', '4', '0', 'TeamPos', 'TeamB'], 
 ['Name3', '4 (1)', '2', '1', '0', 'TeamPos', 'TeamC']]

Expected output would be - lets say I wanted the max value across all lists in index 2:

Name2, 5

EDIT: Trying to pass in data from my first function into the function suggested by slider, and I get NameError: name 'data' is not defined. I've also tried to pass in when get_max is called and that didnt work either

def get_max(lst, i, key_func=None):

    data = squads()

    if not key_func: key_func = lambda x: x[i]
    res = max(lst, key=key_func)
    return [res[0], res[i]]

print(get_max(data,2, lambda x: int(x[2])))

Also, if I try the below and then run it, I get the following error "Position arguement follows keyword argument. I tried to then shift the order in which the values are declared when the function is declared but it gets messy, especially when I dont really follow how this function works

print(get_max(data=squads(),2, lambda x: int(x[2])))

Upvotes: 0

Views: 112

Answers (3)

slider
slider

Reputation: 12990

You can also use max with a key:

data = [['Name1', '1 (5)', '0', '0', '0', 'TeamPos', 'TeamA'], 
        ['Name2', '13 (0)', '5', '4', '0', 'TeamPos', 'TeamB'], 
        ['Name3', '4 (1)', '2', '1', '0', 'TeamPos', 'TeamC']]

def get_max(lst, i, key_func=None):
    if not key_func: key_func = lambda x: x[i]
    res = max(lst, key=key_func)
    return [res[0], res[i]]

print(get_max(data, 2, lambda x: int(x[2])))
# ['Name2', '5']

print(get_max(data, 6))
# ['Name3', 'TeamC']

The way get_max works is you specify your 2-d list, the index you want to retrieve and a key function that you want to pass in to max. If the key function is not provided, a default is used (specifically, lambda x: x[i]).

The key function is supposed to define which column to consider to determine the maximum of your 2-d list.

Edit

You're defining data inside the get_max function but you're using it outside the function. Change this to the following:

def get_max(lst, i, key_func=None):
    if not key_func: key_func = lambda x: x[i]
    res = max(lst, key=key_func)
    return [res[0], res[i]]

data = squads()
print(get_max(data,2, lambda x: int(x[2])))

Upvotes: 3

Jay
Jay

Reputation: 2858

If the data is very large, you may want to isolate your column of interest and do a "lazy" run of max:

list_of_lists = [..] # your data
target_idx = 2
col_of_interest = ((lst[target_idx], idx) for idx, lst in enumerate(list_of_lists))
max_val, location = max(col_of_interest)
print (list_of_lists[location][0], max_val)
# Name2 5

This generates no intermediate lists (or lists of lists thereof).

As noted by @Austin, max() may not provide the result you wanted since the items are strings, in which case you may want to preorganize the lazy column with int():

col_of_interest = ((int(lst[target]), idx) for idx, lst in enumerate(list_of_lists))

Upvotes: 0

DYZ
DYZ

Reputation: 57033

Sorting would be quite appropriate. Let's say you are interested in the 2nd column:

POS = 2
maximal = sorted(your_list, key=lambda x: x[POS])[-1]
[maximal[0], maximal[POS]]
#['Name2', '5']

Bear in mind that sorted sorts strings in the lexicographic order. If you want to treat your columns as numbers, convert them to numbers when sorting:

maximal = sorted(your_list, key=lambda x: int(x[POS]))[-1]

Upvotes: 1

Related Questions