Индекс максимального элемента в массиве кортежей

#python

#python

Вопрос:

Как я могу найти индекс наибольшего значения для кортежей в списке за короткое количество строк кода?

Я мог бы сделать это, используя два цикла for, но я не мог сделать это короче.

например:

 [(0, 0.51634575), (1, 0.113904804), (2, 0.7697494)]
[(0, 0.20560692), (1, 0.141724408), (2, -0.112972)]
[(0, 0.11324576), (1, 0.77262518), (2, 0.11417362)]
  

должен возвращать

 2
0
1
  

которые являются первыми значениями (индексами) кортежей.

вот что я попробовал:

 a= [(0, 0.11324576), (1, 0.77262518), (2, 0.11417362)]

max = max([x[1] for x in a])
id=-1
for x in a:
    if x[1] == max:
        id = x[0]
        break

print(id)
  

Комментарии:

1. «Я мог бы сделать это, используя два цикла for» <- Пожалуйста, покажите нам эту попытку, чтобы мы могли лучше помочь вам.

2. Было бы здорово, если бы вы могли включить и свой код, чтобы мы могли видеть, какие части следует улучшить.

3. Наибольший на основе какого значения в кортеже?

4. что-то вроде [max(a) для a в [max (b) для b в list_of_tupled]]]

5. обновил вопрос моим кодом

Ответ №1:

Вы можете использовать оператор itemgetter() в качестве ключа в функции max() :

 from operator import itemgetter

l = [[(0, 0.51634575), (1, 0.113904804), (2, 0.7697494)], [(0, 0.20560692), (1, 0.141724408), (2, -0.112972)], [(0, 0.11324576), (1, 0.77262518), (2, 0.11417362)]]

get1 = itemgetter(1)
[max(i, key=get1)[0] for i in l]
# [2, 0, 1]
  

Ответ №2:

Это некрасиво, но это должно сработать:

 l = [(0, 0.51634575), (1, 0.113904804), (2, 0.7697494)]
l[l.index((_, max([tuple[1] for tuple in l])))][0]
  

Вывод:

 2
  

Конечно, спорно, не является ли это двумя циклами for.

Другое решение, которое использует только один цикл for, будет выглядеть следующим образом:

 max_index = -1
max_val = -1
for (index, value) in l:
    if value > max_val:
        max_index = index
        max_val = value
return max_index
  

Ответ №3:

Для одного списка:

 b = [(0, 0.11324576), (1, 0.77262518), (2, 0.11417362)]

n = [x[1] for x in b]
print(b[n.index(max(n))][0])
  

Ответ №4:

Используйте enumerate:

 i_max=0
for i,t in enumerate(a):
    if (a[i][1] > a[i_max][1]):
        i_max = i
print(i_max)
  

Без использования enumerate (предполагая, что первый элемент кортежа всегда равен индексу кортежа в списке кортежей):

 i_max=0
for t in a:
    if (t[1] > a[i_max][1]):
        i_max = t[0]
print(i_max)
  

Ответ №5:

если данные похожи на эти

 a = [[(0, 0.51634575), (1, 0.113904804), (2, 0.7697494)],
[(0, 0.20560692), (1, 0.141724408), (2, -0.112972)],
[(0, 0.11324576), (1, 0.77262518), (2, 0.11417362)]]
  

затем

 result = [max(lis,key = lambda x :x[1])[0] for lis in a]
  

Ответ №6:

Базовый уровень:

 test_set = [
  [(0, 0.51634575), (1, 0.113904804), (2, 0.7697494)],
  [(0, 0.20560692), (1, 0.141724408), (2, -0.112972)],
  [(0, 0.11324576), (1, 0.77262518), (2, 0.11417362)],
]
  

Это самая короткая версия без слишком большого количества кода.:

 for test in test_set:
  c, v = zip(*test)
  result = c[v.index(max(v))]
  print(result)
  

И потому, что игра в гольф с кодом на самом деле увлекательна:

 for t in test_set:print(max(t,key=lambda x:x[1])[0])
  

Это наиболее эффективная версия для выполнения и, вероятно, также наиболее экономичная для памяти:

 for test in test_set:
  max_elem = test[0]
  for tup in test:
    if tup[1] > max_elem[1]:
      max_elem = tup
  print(max_elem[0])
  

Результаты всех приведенных выше фрагментов:

 2
0
1
  

Комментарии:

1. При этом index() вы получаете O(N^2) временную сложность. Та же эффективность при использовании двойного for цикла.

2. @MykolaZotko ага. Вот почему я включил последний фрагмент как наиболее эффективный — он должен быть O (N)