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

Мне дали задание найти наибольшее значение в списке с помощью лямбда-функции. С лямбда-функцией у меня должно быть два параметра, и мне трудно получить элементы из списка для использования в лямбда-функции.

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

myList = [1,2,3,4,5,6,7,8,9,10]

#Here I can find the max value by defining a function

def maxVal(list_a):

   max = 0

   for i in list_a:

       if i > max:
          max = i
   return max
print(maxVal(myList))

#Here I attempt to use a lambda function to find the max value

maxMyList = map(lambda x,y: x[0] >= y[0], myList, myList)

print(maxMyList(myList,myList))

Редактировать: Извините за путаницу, так как я впервые публикую здесь. Просто для ясности, я НЕ МОГУ определить какие-либо функции для использования в этой программе. Я просто хотел опубликовать код для определенной функции maxVal, чтобы показать, что я понимаю логику того, что мне нужно делать. Спасибо за все ответы, мне очень приятно!

Вот подсказка: как бы вы определили лямбду, чтобы найти самый большой элемент в списке из двух элементов? Теперь представьте, что ваш список [a,b,c] состоит из двухэлементных списков: [[a,b], c].

c2huc2hu 10.04.2019 01:40

Вы должны использовать сокращение?

Kevin Wang 10.04.2019 01:44

Не уверен, что map является правильной функцией в данном случае. map применит функцию lambda к каждому элементу вашего списка, результатом будет генератор (который можно преобразовать в список), а не одно число

Valentino 10.04.2019 01:46

Еще одна подсказка: lambda в Python — это просто специальный синтаксис для определения функции в одной строке. Она не имеет особого значения по сравнению с любой другой функцией. Другими словами, вы можете передать любую функцию map(). Его не обязательно определять с помощью синтаксиса lambda. Итак, попробуйте определить функцию my_max(x, y), которая работает так же, но также печатает аргументы x и y и, возможно, посмотрите, что происходит.

Iguananaut 10.04.2019 01:49
(lambda x: max(x))(myList) ;) Но в любом случае, да, вы почти наверняка должны использовать reduce, map здесь не имеет смысла.
juanpa.arrivillaga 10.04.2019 01:52

@Iguananaut, отличное предложение! Сделайте все так, как он предлагает, а затем просто преобразуйте свою обычную функцию в лямбду в конце. Единственное, что я хочу добавить, это то, что лямбда-выражения почти всегда (всегда?) передаются в другие функции. Но вы также можете передать обычную функцию в другую функцию. Так что сначала сделайте это, а затем перейдите на лямбду. - вы можете просто использовать обычный цикл для накопления максимального значения, которое вы видели до сих пор, или вы можете проявить фантазию и использовать functools.reduce()

CryptoFool 10.04.2019 01:54

Я также укажу, что ваши образцы данных не являются отличным тестовым образцом. Это слишком упорядоченно. Это может легко не вызвать проблем с вашим алгоритмом, который мог бы поймать больше зашифрованных данных. - например, если ваша тестовая функция всегда возвращает самое новое значение при переборе списка, вы получите правильный ответ, но по неправильной причине.

CryptoFool 10.04.2019 01:57

@juanpa.arrivillaga Это не использует 2 параметра, как требуется. Требование использования 2 параметров подразумевает здесь рекурсивное решение ИМХО.

blhsing 10.04.2019 02:05

@blhsing, это была шутка, отсюда и подмигивающий смайлик ... В любом случае, я думаю, что это явно предназначалось для сокращения, которое берет двоичную операцию и итерацию и сводит ее к одному значению. Кроме того, просто предполагая, что, поскольку ОП думал использовать карту. В любом случае, да, использовать лямбду для рекурсии просто некрасиво. Конечно, только тот, кто поставил эту задачу, может знать, что он надеялся увидеть в решении.

juanpa.arrivillaga 10.04.2019 02:09
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
9
8 016
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы можете определить функцию, которая принимает список в качестве первого параметра и, при необходимости, текущий максимум в качестве второго параметра, и рекурсивно вызывает себя с первым элементом в списке в качестве второго аргумента, если он больше текущего максимума или если текущий максимум равно None, а остальную часть списка в качестве первого аргумента, пока остальная часть списка не станет пустой, после чего возвращает текущий максимум:

maxVal = lambda lst, m=None: maxVal(lst[1:], m if m is not None and lst[0] < m else lst[0]) if lst else m

так что:

from random import shuffle
myList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
shuffle(myList)
print(maxVal(myList))

выходы: 10

Ответ принят как подходящий

На самом деле нет ничего плохого в том, как вы это делаете. Вам просто нужно было правильно включить вашу лямбду в остальную часть вашего кода:

myList = [1,2,3,10,4,5,6,7,8,9]

def maxVal(list_a, compare_function):
    max = -sys.maxsize - 1  # strange but true...this seems to be the canonical way to get the smallest 32 bit `int`
    for i in list_a:
        if compare_function(i, max):
            max = i
    return max

my_compare_function = lambda x,y: max(x, y)

print(maxVal(myList, my_compare_function))

Результат:

10

Мне действительно пришлось изменить уровень вызова return max. Я не знаю, была ли это логическая ошибка или просто ошибка транскрипции, когда вы помещаете свой код в S.O. вопрос. Также обратите внимание, что я переместил 10 в другое место в ваших входных данных, чтобы убедиться, что оно не должно быть в конце, чтобы быть найденным как наибольшее значение.

Если вам нужен «более крутой» и современный ответ, reduce действительно предназначен для того, чтобы делать именно то, что вы хотите. Вот простое решение.

import functools

myList = [1,2,3,10,4,5,6,7,8,9]
r =  functools.reduce(lambda v1, v2: max(v1, v2), myList)
print(r)

Результат:

10

Также обратите внимание, что «max» сама по себе является функцией, которая принимает два параметра, поэтому вы можете использовать ее напрямую, чтобы получить что-то очень простое... не то, чтобы это работало в вашем случае, когда ваше назначение заключается в использовании лямбда:

myList = [1,2,3,10,4,5,6,7,8,9]
r =  functools.reduce(max, myList)
print(r)

Эти функциональные эквиваленты написания циклов очень популярны, и на то есть веские причины. В сочетании с обработкой данных в виде потоков это очень мощная идея. И по мере того, как он становится все более популярным, я думаю, что он станет более читабельным. Как старый таймер, я только начинаю разбираться со всем этим функциональным / потоковым программированием ... больше на Java, чем на Python, но все же. Это мощный набор инструментов, который поможет вам действительно хорошо понять.

Использование max кажется глупым. Наверное, я бы хотел посмотреть lambda x,y : x if x >= y else y, если бы это было задание, которое я дал. Конечно, я бы никогда не ввел абсурдное ограничение вроде «использовать лямбда-функцию…».

juanpa.arrivillaga 10.04.2019 02:11

Да, я понимаю. Было бы круто, если бы инструктор придумал что-то более интересное, чем переписывание функции 'max' в виде лямбды. В данном случае я считаю глупым изобретать велосипед. - но «вы не можете использовать max», безусловно, добавили бы немного дополнительного интереса к проблеме. И если бы это был я, я бы посмотрел на реализацию «max» и все равно украл бы этот код :)

CryptoFool 10.04.2019 02:13
max = -sys.maxsize - 1 не подходит для типа int python произвольного размера. Используйте floa('-inf')
juanpa.arrivillaga 10.04.2019 03:59

Я знаю это. Я хотел просто «очень маленькое число», а не «самое маленькое число». Вот почему я квалифицировал свой комментарий как «32-битный». Я думал об использовании float(-inf), но нам нужен тип int. Мне было не очень комфортно во всем этом. В основном я просто хотел допустить разумные отрицательные значения в данных, которые сломали бы вещи, как изначально было написано. Почему P3 не поддерживает int(-inf)? Я думаю, потому что «inf» - это концепция с плавающей запятой. Но тогда как вы ожидали, что мы применим это к установке int?

CryptoFool 10.04.2019 04:21

Мне никогда не приходилось иметь дело с понятием бесконечно большого целочисленного типа на уровне языка. Я использовал BigInteger в java, но ничего такого «волшебного», как это.

CryptoFool 10.04.2019 04:28

Потому что числовые типы сопоставимы. Конечно, вы можете реализовать свой собственный тип, который всегда меньше или больше целого числа. Или всегда возвращает true для всех сравнений, или всегда false...

juanpa.arrivillaga 10.04.2019 04:31

В Python есть встроенная функция для сортировки списков. Это sorted()

Пример: sorted([2, 8, 8, 3, 7, 4, 2, 93, 1]) = [1, 2, 2, 3, 4, 7, 8, 8, 93]

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

maxVal = lambda l: sorted(l)[::-1][0]

Этот парень спрашивает о чем-то рекурсивном.

Edward Aung 10.04.2019 02:25

Даже если это соответствует тому, что искал ОП, чего я не думаю, это гораздо менее эффективный способ решения проблемы. Вам придется проделать немного больше работы, чтобы отсортировать массив, и это в любом случае потребует обхода массива. Гораздо эффективнее рассматривать каждый элемент ровно один раз и не копировать, как это делают другие ответы. Вы даже вводите дополнительное копирование всего набора данных, чтобы отменить его, вместо того, чтобы использовать опцию sorted() reverse.

CryptoFool 10.04.2019 02:59
max= (lambda x, y: x if x > y else y)

max(1, 2)

Можете ли вы добавить некоторый контекст, чтобы объяснить, как это ответит на вопрос, а не ответ только на код.

Arun Vinoth - MVP 15.01.2020 16:54

Другие вопросы по теме