Почему мы использовали лямбду в качестве аргумента функции здесь? - PullRequest
0 голосов
/ 29 апреля 2018

Несколько вопросов по приведенному ниже коду, чтобы найти, отсортирован ли список или нет:

Почему мы использовали лямбду в качестве ключа здесь? Всегда ли это означает, что ключ списка может быть получен так?

Почему в цикле перечисления мы сравнили key(el) < key(lst[i]), а не key(el) <key(el-1) или lst[i+1] <lst[i]?

def is_sorted(lst, key=lambda x:x):
    for i, el in enumerate(lst[1:]):
        if key(el) < key(lst[i]): # i is the index of the previous element
            return False
    return True

hh=[1,2,3,4,6]
val = is_sorted(hh)
print(val)  

(Примечание: код, приведенный выше, был взят из этого ответа SO )

Ответы [ 4 ]

0 голосов
/ 29 апреля 2018

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

Например, допустим, вы хотите отсортировать кортежи, но на основании третьего элемента, который, как вы знаете, является целым числом, это будет key=lambda x: x[2]. Но автор предоставляет значение по умолчанию key=lamba x:x, которое просто возвращает предоставленный объект для элементов, которые уже имеют свой собственный ключ сортировки.

Вторая часть проста. Если какой-либо элемент меньше, чем элемент непосредственно перед ним, то мы нашли пример, где его от низкого до высокого. Причина, по которой это работает, буквально в комментарии - i - это индекс элемента, непосредственно предшествующего el. Мы знаем это, потому что перечислили второй и последующие элементы списка (enumerate(lst[1:]))

0 голосов
/ 29 апреля 2018

Дело не в том, что лямбда "выводит" ключ списка. Скорее, это функция, которая позволяет вам выбирать ключ. То есть, учитывая список объектов типа X, с каким атрибутом вы бы их сравнили? По умолчанию используется функция тождества, т.е. используется простое значение каждого элемента. Но вы можете выбрать здесь что угодно.

Вы действительно могли бы написать эту функцию, сравнив lst[i+1] < lst[i]. Однако вы не могли бы написать это, сравнив key(el) < key(el-1), потому что el - это значение самого элемента, а не индекса.

0 голосов
/ 29 апреля 2018

Это функция, которая проверяет, отсортирован ли список, как, например, встроенная функция sorted. Эта функция принимает ключевое слово аргумента key, которое используется для каждого элемента в списке для вычисления его значения сравнения:

>>> sorted([(0,3),(1,2),(2,1),(3,0)])
[(0, 3), (1, 2), (2, 1), (3, 0)]
>>> sorted([(0,3),(1,2),(2,1),(3,0)],key=lambda x:x[1])
[(3, 0), (2, 1), (1, 2), (0, 3)]

Ключевое слово key в вашей функции должно имитировать поведение sorted:

>>> is_sorted([(0,3),(1,2),(2,1),(3,0)])
True
>>> is_sorted([(0,3),(1,2),(2,1),(3,0)],key=lambda x:x[1])
False

Значение по умолчанию lambda просто имитирует поведение по умолчанию, когда ничего не меняется.

0 голосов
/ 29 апреля 2018

enumerate возвращает индекс и текущий элемент:

for i, el in enumerate(lst):
    print(i,el)

будет печатать:

0 1
1 2
2 3
3 4
4 6

Срезая список по одному (удаляя первый элемент), код вводит сдвиг между индексом и текущим элементом и позволяет получить доступ по индексу только один раз (не рассматривается как пиктоническое использование индексов в списках, когда итерируя на них полностью)

Это все еще лучше / список с питанием в zip (чередование) и нарезанную версию списка и передать сравнение в all, без индексов, более ясный код:

import itertools

def is_sorted(lst, key=lambda x:x):
    return all(key(current) < key(prev) for prev,current in zip(lst,itertools.islice(lst,1,None,None)))

Срезы выполняются islice, дополнительный список не генерируется (в противном случае это то же самое, что lst[1:])

Ключевая функция (здесь: функция идентичности по умолчанию) - это функция, которая преобразует значение в сопоставимое значение. Для целых чисел идентичность в порядке, если мы не хотим обратного сравнения, в этом случае мы передадим lambda x:-x

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...