Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting by attributes that can be None

Let's say I have a list of items I want to sort: items = [ item1, item2, item3 ]. The attribute I want to use to sort them is item.data.value, so I'd normally go:

sorted(items, key=attrgetter('data.value'))

And that'd work just fine. However, data can actually be None so obviously I couldn't access value.

How do you usually deal with scenarios like this?

PS: neither this question nor this one helped.

like image 669
dabadaba Avatar asked Sep 19 '16 11:09

dabadaba


People also ask

Does sorted mutate list?

key is a function that generates an intermediate value for each element, and this value is used to do the comparisons during the sorting process. The sort() method mutates the list, causing permanent changes. You need to be very careful and only use it if you do not need the original version of the list.

How do you sort a list by key?

sort() Syntax The syntax of the sort() method is: list.sort(key=..., reverse=...) Alternatively, you can also use Python's built-in sorted() function for the same purpose.

Can you sort objects in Python?

Python lists have a built-in list.sort() method that modifies the list in-place. There is also a sorted() built-in function that builds a new sorted list from an iterable.

How do you sort an array by key in Python?

To sort a dictionary by value in Python you can use the sorted() function. Python's sorted() function can be used to sort dictionaries by key, which allows for a custom sorting method. sorted() takes three arguments: object, key, and reverse .


2 Answers

sorted(items, key=lambda i: i.data.value if i.data else 0)
like image 169
Sergey Gornostaev Avatar answered Nov 13 '22 08:11

Sergey Gornostaev


Use as key a tuple, like (False, value). If value is None, then the tuple should be (True, None).

Tuples are compared by their first element first, then the second, et cetera. False sorts before True. So all None values will be sorted to the end.

def none_to_end_key(item):
    value = item.data.value if item.data else None
    return (value is None, value)

sorted(items, key=none_to_end_key)

Will sort all None values to the end.

I see now that you have tagged your question Python-2.7, then this is probably overkill. In Python 3, comparing None to an integer or string raises an exception, so you can't simply sort a list with None and other values, and something like this is needed.

like image 39
RemcoGerlich Avatar answered Nov 13 '22 09:11

RemcoGerlich