Поиск самого яркого цвета из предложенных в формате "#000000"
def brightest(colors):
return max(colors, key=lambda c:max(c[1:3], c[3:5], c[5:]))
Это решение одной из кат на CodeWars. Задача была найти самый яркий цвет RGB из списка. Конкретно непонятен метод сортировки key
Ниже представлено то, как бы проверялся верхний код и какой результат должен был быть
test.assert_equals(brightest(["#001000", "#000000"]), "#001000")
test.assert_equals(brightest(["#ABCDEF", "#123456"]), "#ABCDEF")
test.assert_equals(brightest(["#00FF00", "#FFFF00"]), "#00FF00")
test.assert_equals(brightest(["#FFFFFF", "#1234FF"]), "#FFFFFF")
Ответы (3 шт):
Всё в принципе просто. У нас есть цвет #001000, в нём заложена следующая структура #RRGGBB.
На сколько я понимаю идею приложенного кода, то наиболее ярким считается цвет, в котором значение одного из R,G,B цвета выше.
Так же стоит прояснить, что в функции max, как и в фукнции sorted, есть аргумент key, который помогает кастомизировать сортировку под себя. Об этом можно почитать здесь.
При задании аргумента key функцией, каждый аргумент переданный на сортировку передаётся в функцию key, которая должна обработать элемент и выдать некую оценку элемента. После оценки элемента, вступает обычная сущность функции max, найти наибольшее значение.
Так же можно увидеть всё глазами тут.
c[1:3], c[3:5], c[5:]достает из каждого переданного цветаRGB-hexзначения. Чем больше каждое значение - тем ярче цвет.- За счет того, что символы в
pythonимеют сравнение, подходящее для цветов (меньше буква/цифра цвета - тусклее цвет), мы можем воспользоваться функциейmax(c[1:3], c[3:5], c[5:]), которая выберет самый яркий из трех составляющих. max(colors, key=lambda c:max(c[1:3], c[3:5], c[5:]))выбирает максимальный элемент изcolorsпо заданному ключу, работа которого описана выше.
В первую очередь, заголовок
«Поиск самого яркого цвета ...»
не соответствует предложенной функции. Эта функция делает что-то другое, именно
- Поиск цвета с наиболее ярким компонентом в системе RGB
т.е. цвета, в котором один из компонентов (красный, зеленый, синий) более какого-нибудь компонента в остальных цветах (точнее, не менее, т.к. может случиться и равенство).
Теперь к самой функции max().
Она может заниматься так
- сравниванием самых элементов (чтобы определить набольший из них),
как и
- сравниванием какой-то черты (свойства) этих элементов (чтобы определить элемент с наибольшей такой чертой).
(Примерь: Можем сравнивать людей для возраста, для веса, или для высоты, и искать соответственно человека с набольшим возрастом, весом или высотой.)
Когда мы хотим сравнивать для какой-то черты, нужно в параметр key= задать функцию, которая каждому (сравниваемую) элементу определит такую черту.
Например
max("Маша", "Альбина", key=len)
(т.е. сравнивание для количества букв в имени) выдает "Альбина", хотя она в алфавитном упорядочении менее Маши.
Но и, наконец, к самому вашему примеру.
key=lambda c: max(c[1:3], c[3:5], c[5:])
Ламбда-функция присвоит каждому цвету (здесь обозначенному именем c) максимальное значение из его компонент (красной, зеленой, синей)...
Значит, сравниваться будут не строки типа "#RRGGBB", а двухзнаковие строки в диапазоне от "00" до "FF".
Замечание:
Что такое ламбда-функция?
Когда нам нужна функция (как например в ключевом параметре key= функции max(),
- но мы будем использовать ее только один раз, и
- она довольно простая
to вместо
долгого определения перед ее применением, и
нужности придумать для ее какое-то имя:
def lightest_component(c): return max(c[1:3], c[3:5], c[5:])и - наконец - ее применением:
max(colors, key=lightest_component)
мы можем это сделать в одном шаге:
max(colors, key=lambda c:max(c[1:3], c[3:5], c[5:]))
Определение ламбда функции начинается словом
lambda
затем следует список параметров
lambda par1, par2, par3
затем двоеточие (как признак конца списка параметров)
lambda par1, par2, par3:
и наконец выражение — вычисление значения, которое будет функция возвращать:
lambda par1, par2, par3: par1 + par2 - par3
То-же самое в сжатой форме, как оно обычно используется:
lambda a,b,c: a+b-c