Мне дали задание найти наибольшее значение в списке с помощью лямбда-функции. С лямбда-функцией у меня должно быть два параметра, и мне трудно получить элементы из списка для использования в лямбда-функции.
Я понимаю, как выполнить задачу, определив функцию, но я не знаю, как перевести это в лямбда-функцию.
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, чтобы показать, что я понимаю логику того, что мне нужно делать. Спасибо за все ответы, мне очень приятно!
Вы должны использовать сокращение?
Не уверен, что map
является правильной функцией в данном случае. map
применит функцию lambda
к каждому элементу вашего списка, результатом будет генератор (который можно преобразовать в список), а не одно число
Еще одна подсказка: lambda
в Python — это просто специальный синтаксис для определения функции в одной строке. Она не имеет особого значения по сравнению с любой другой функцией. Другими словами, вы можете передать любую функцию map()
. Его не обязательно определять с помощью синтаксиса lambda
. Итак, попробуйте определить функцию my_max(x, y)
, которая работает так же, но также печатает аргументы x
и y
и, возможно, посмотрите, что происходит.
(lambda x: max(x))(myList)
;) Но в любом случае, да, вы почти наверняка должны использовать reduce
, map
здесь не имеет смысла.
@Iguananaut, отличное предложение! Сделайте все так, как он предлагает, а затем просто преобразуйте свою обычную функцию в лямбду в конце. Единственное, что я хочу добавить, это то, что лямбда-выражения почти всегда (всегда?) передаются в другие функции. Но вы также можете передать обычную функцию в другую функцию. Так что сначала сделайте это, а затем перейдите на лямбду. - вы можете просто использовать обычный цикл для накопления максимального значения, которое вы видели до сих пор, или вы можете проявить фантазию и использовать functools.reduce()
Я также укажу, что ваши образцы данных не являются отличным тестовым образцом. Это слишком упорядоченно. Это может легко не вызвать проблем с вашим алгоритмом, который мог бы поймать больше зашифрованных данных. - например, если ваша тестовая функция всегда возвращает самое новое значение при переборе списка, вы получите правильный ответ, но по неправильной причине.
@juanpa.arrivillaga Это не использует 2 параметра, как требуется. Требование использования 2 параметров подразумевает здесь рекурсивное решение ИМХО.
@blhsing, это была шутка, отсюда и подмигивающий смайлик ... В любом случае, я думаю, что это явно предназначалось для сокращения, которое берет двоичную операцию и итерацию и сводит ее к одному значению. Кроме того, просто предполагая, что, поскольку ОП думал использовать карту. В любом случае, да, использовать лямбду для рекурсии просто некрасиво. Конечно, только тот, кто поставил эту задачу, может знать, что он надеялся увидеть в решении.
Вы можете определить функцию, которая принимает список в качестве первого параметра и, при необходимости, текущий максимум в качестве второго параметра, и рекурсивно вызывает себя с первым элементом в списке в качестве второго аргумента, если он больше текущего максимума или если текущий максимум равно 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
, если бы это было задание, которое я дал. Конечно, я бы никогда не ввел абсурдное ограничение вроде «использовать лямбда-функцию…».
Да, я понимаю. Было бы круто, если бы инструктор придумал что-то более интересное, чем переписывание функции 'max' в виде лямбды. В данном случае я считаю глупым изобретать велосипед. - но «вы не можете использовать max», безусловно, добавили бы немного дополнительного интереса к проблеме. И если бы это был я, я бы посмотрел на реализацию «max» и все равно украл бы этот код :)
max = -sys.maxsize - 1
не подходит для типа int
python произвольного размера. Используйте floa('-inf')
Я знаю это. Я хотел просто «очень маленькое число», а не «самое маленькое число». Вот почему я квалифицировал свой комментарий как «32-битный». Я думал об использовании float(-inf)
, но нам нужен тип int. Мне было не очень комфортно во всем этом. В основном я просто хотел допустить разумные отрицательные значения в данных, которые сломали бы вещи, как изначально было написано. Почему P3 не поддерживает int(-inf)
? Я думаю, потому что «inf» - это концепция с плавающей запятой. Но тогда как вы ожидали, что мы применим это к установке int?
Мне никогда не приходилось иметь дело с понятием бесконечно большого целочисленного типа на уровне языка. Я использовал BigInteger в java, но ничего такого «волшебного», как это.
Потому что числовые типы сопоставимы. Конечно, вы можете реализовать свой собственный тип, который всегда меньше или больше целого числа. Или всегда возвращает true для всех сравнений, или всегда false...
В 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]
Этот парень спрашивает о чем-то рекурсивном.
Даже если это соответствует тому, что искал ОП, чего я не думаю, это гораздо менее эффективный способ решения проблемы. Вам придется проделать немного больше работы, чтобы отсортировать массив, и это в любом случае потребует обхода массива. Гораздо эффективнее рассматривать каждый элемент ровно один раз и не копировать, как это делают другие ответы. Вы даже вводите дополнительное копирование всего набора данных, чтобы отменить его, вместо того, чтобы использовать опцию sorted() reverse
.
max= (lambda x, y: x if x > y else y)
max(1, 2)
Можете ли вы добавить некоторый контекст, чтобы объяснить, как это ответит на вопрос, а не ответ только на код.
Вот подсказка: как бы вы определили лямбду, чтобы найти самый большой элемент в списке из двух элементов? Теперь представьте, что ваш список
[a,b,c]
состоит из двухэлементных списков:[[a,b], c]
.