Valor máximo de una lista de listas y su índice

li = [[1,2], [2,3], [7,6]] 

¿Cómo puedo encontrar el valor máximo y su índice de manera eficiente? Supongamos que para li quiero:

 max_value = 7 max_index = (2, 0) 

Puedo hacer esto de la siguiente manera:

 max_value = 0 for row_idx, row in enumerate(alignment_matrix): for col_idx, col in enumerate(row): if col > max_value: max_value = col max_index = (row_idx, col_idx) 

Pero necesito una forma eficiente sin usar demasiadas variables innecesarias.

Usando max y la expresión del generador , puedes expresslo más en breve:

 max_value, max_index = max((x, (i, j)) for i, row in enumerate(li) for j, x in enumerate(row)) 

Pero, la complejidad del tiempo es la misma porque esta también usa un bucle nested.

ACTUALIZAR

Como señaló @jonrsharpe, en el caso de duplicar max_value s, la solución anterior le dará el índice más grande en el que se encuentra el valor.

Si eso no es lo que desea, puede pasar el argumento de la función key a max para personalizar el comportamiento:

 max_value, max_index = max(((x, (i, j)) for i, row in enumerate(li) for j, x in enumerate(row)), key=lambda (x, (i, j)): (x, -i, -j)) 

Puedes hacer algo como:

 max(data, key=lambda x: x[0]) 

O, una alternativa más eficiente:

 max(data, key=operator.itemgetter(0)) 

Aquí está la comparación de tiempo:

 In [11]: timeit.timeit('max(data, key=lambda x: x[0])', setup='import operator, random; data=[[random.randint(1,100) for _ in range(100)] for _ in range(100)]') Out[11]: 8.272005081176758 In [12]: timeit.timeit('max(data, key=operator.itemgetter(0))', setup='import operator, random; data=[[random.randint(1,100) for _ in range(100)] for _ in range(100)]') Out[12]: 5.0041139125823975