Подтвердить что ты не робот

Список сортировки Python с None в конце

У меня есть однородный список объектов с None, но он может содержать значения любого типа. Пример:

>>> l = [1, 3, 2, 5, 4, None, 7]
>>> sorted(l)
[None, 1, 2, 3, 4, 5, 7]
>>> sorted(l, reverse=True)
[7, 5, 4, 3, 2, 1, None]

Есть ли способ без повторного изобретения колеса, чтобы получить список, отсортированный обычным способом Python, но с None-значениями в конце списка, например:

[1, 2, 3, 4, 5, 7, None]

Я чувствую, что здесь может быть какая-то хитрость с параметром "ключ"

4b9b3361

Ответ 1

>>> l = [1, 3, 2, 5, 4, None, 7]
>>> sorted(l, key=lambda x: (x is None, x))
[1, 2, 3, 4, 5, 7, None]

Это строит кортеж для каждого элемента в списке, если значение None кортеж с be (True, None), если значение - это что-то еще, это будет (False, x) (где x - значение), Поскольку кортежи сортируются по элементам, это означает, что все элементы не None будут первыми (начиная с False < True), а затем будут отсортированы по значению.

Ответ 2

Попробуйте следующее:

sorted(l, key=lambda x: float('inf') if x is None else x)

Так как бесконечность больше всех целых чисел, None всегда будет помещаться последним.

Ответ 3

Я создал функцию, которая расширяет ответ эндрю Кларка и комментарий tutuDajuju.

def sort(myList, reverse = False, sortNone = False):
    """Sorts a list that may or may not contain None.
    Special thanks to Andrew Clark and tutuDajuju for how to sort None on https://stackoverflow.com/info/18411560/python-sort-list-with-none-at-the-end

    reverse (bool) - Determines if the list is sorted in ascending or descending order

    sortNone (bool) - Determines how None is sorted
        - If True: Will place None at the beginning of the list
        - If False: Will place None at the end of the list
        - If None: Will remove all instances of None from the list

    Example Input: sort([1, 3, 2, 5, 4, None, 7])
    Example Input: sort([1, 3, 2, 5, 4, None, 7], reverse = True)
    Example Input: sort([1, 3, 2, 5, 4, None, 7], reverse = True, sortNone = True)
    Example Input: sort([1, 3, 2, 5, 4, None, 7], sortNone = None)
    """

    return sorted(filter(lambda item: True if (sortNone != None) else (item != None), myList), 
        key = lambda item: (((item is None)     if (reverse) else (item is not None)) if (sortNone) else
                            ((item is not None) if (reverse) else (item is None)), item), 
        reverse = reverse)

Вот пример того, как вы можете запустить его:

myList = [1, 3, 2, 5, 4, None, 7]
print(sort(myList))
print(sort(myList, reverse = True))
print(sort(myList, sortNone = True))
print(sort(myList, reverse = True, sortNone = True))
print(sort(myList, sortNone = None))
print(sort(myList, reverse = True, sortNone = None))