Поиск самого яркого цвета из предложенных в формате "#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 шт):

Автор решения: Ternick

Всё в принципе просто. У нас есть цвет #001000, в нём заложена следующая структура #RRGGBB.

На сколько я понимаю идею приложенного кода, то наиболее ярким считается цвет, в котором значение одного из R,G,B цвета выше.

Так же стоит прояснить, что в функции max, как и в фукнции sorted, есть аргумент key, который помогает кастомизировать сортировку под себя. Об этом можно почитать здесь.

При задании аргумента key функцией, каждый аргумент переданный на сортировку передаётся в функцию key, которая должна обработать элемент и выдать некую оценку элемента. После оценки элемента, вступает обычная сущность функции max, найти наибольшее значение.

Так же можно увидеть всё глазами тут.

→ Ссылка
Автор решения: n1tr0xs
  1. c[1:3], c[3:5], c[5:] достает из каждого переданного цвета RGB-hex значения. Чем больше каждое значение - тем ярче цвет.
  2. За счет того, что символы в python имеют сравнение, подходящее для цветов (меньше буква/цифра цвета - тусклее цвет), мы можем воспользоваться функцией max(c[1:3], c[3:5], c[5:]), которая выберет самый яркий из трех составляющих.
  3. max(colors, key=lambda c:max(c[1:3], c[3:5], c[5:])) выбирает максимальный элемент из colors по заданному ключу, работа которого описана выше.
→ Ссылка
Автор решения: MarianD

В первую очередь, заголовок

«Поиск самого яркого цвета ...»

не соответствует предложенной функции. Эта функция делает что-то другое, именно

  • Поиск цвета с наиболее ярким компонентом в системе 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
→ Ссылка