Найти максимальный элемент из списка неравномерных списков - PullRequest
0 голосов
/ 29 мая 2018

У меня есть вложенный список, и я хочу найти максимальное значение элементов в индексе [1].

Вот мой список:

myList = [['apple',2],
          ['banana',4],
          ['orange'],
          ['strawberry',10],
          ['mango']]

Я использовал эту функцию:

 print(max(myList, key=lambda x: x[1]))

Но это дает мне ошибку, потому что у некоторых из списка нет элемента в индексе [1].

Поскольку мой исходный набор данных действительно большой, мне важно использоватьэффективная функция, чтобы проверить, находится ли индекс [1] в myList, затем найти максимум.

Есть ли эффективный способ для этого?Как встроенная функция?Не хочу использовать для цикла, если это возможно.

Ответы [ 4 ]

0 голосов
/ 29 мая 2018

Приветствуются ответы выше.

@ Махса , вы также можете получить максимальное количество фруктов из списка, используя понимание списка , map () , filter () и lower () следующим образом:

Приятно использовать map () , filter () , lower () и понимание списка в программах Pythonic.

Примечание: map (), filter (), Reduce () медленнее, чем их альтернативы цикла, если список огромен.

"Использование map (), функция lamda:

my_list =  [['apple',2],['banana',4],['orange'],['strawberry',10],['mango']];

# Using map() function (1st way)
max_count = max(list(map(lambda item: item[1] if len(item) > 1 else -1, my_list)))
print(max_count) # 10

" Использование filter (),уменьшить ():

# Using filter() and reduce()
from functools import reduce

my_list =  [['apple',2],['banana',67],['orange'],['strawberry',10],['mango']];

def get_max(item1, item2):
    if type (item1)  == type([]):
        if item1[1] > item2[1]:
            return item1[1]
    elif item1 > item2[1]:
            return item1
    return item2[1]

filtered_items = list(filter(lambda item: len(item) > 1, my_list))
max_count2 = reduce(get_max, filtered_items)
print(max_count2) # 67
0 голосов
/ 29 мая 2018

operator.itemgetter + max

Для лучшей производительности, попробуйте предварительную фильтрацию перед вызовом max.Затем вы можете использовать operator.itemgetter, который работает со скоростью C.

>>> from operator import itemgetter
>>> max((i for i in lst if len(i) > 1), key=itemgetter(1))
['strawberry', 10]

Это должно работать как для числовых данных, так и для дат (при условии, что форматирование соответствует), поскольку даты хорошо воспроизводятся при сравнении лексикографически.


zip_longest + np.argmax

Еще одна полезная опция, если у вас установлен NumPy.

>>> import numpy as np
>>> from itertools import zip_longest
>>> _, y = itertools.zip_longest(*lst, fillvalue=-float('inf'))
>>> lst[np.argmax(y)]
['strawberry', 10]

Отказ от ответственности, она работает только с числовыми данными.


lst = lst * 100000

%timeit max(lst, key=lambda x: x[1] if len(x) > 1 else 0)
175 ms ± 1.19 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit max((i for i in lst if len(i) > 1), key=itemgetter(-1))
142 ms ± 875 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%%timeit
_, y = itertools.zip_longest(*lst, fillvalue=-float('inf'))
lst[np.argmax(y)]
136 ms ± 735 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

Если вы можете себе позволить память, позвоните по номеру max в листинговой версии варианта 1:

%timeit max([i for i in lst if len(i) > 1], key=itemgetter(-1))
128 ms ± 976 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

Это, пожалуй, самый эффективный вариант на сегодняшний день.

0 голосов
/ 29 мая 2018

Если вы хотите максимальное значение :

import sys
MIN_INT = -sys.maxsize-1  # Largest negative integer.

myList = [['apple', 2],
          ['banana', 4],
          ['orange'],
          ['strawberry', 10],
          ['mango']]

maximum_value = max(myList, key=lambda item: item[1] if len(item) > 1
                                        else MIN_INT)[1]
print(maximum_value)  # -> 10
0 голосов
/ 29 мая 2018

Вы можете использовать троичный оператор , чтобы задать значение по умолчанию, когда его нет, например:

max(myList, key=lambda x: x[1] if len(x) > 1 else 0)

Результат:

['strawberry', 10]
...