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)
Это, пожалуй, самый эффективный вариант на сегодняшний день.