I'm trying to sort a list of objects using
my_list.sort(key=operator.attrgetter(attr_name))
but if any of the list items has attr = None
instead of attr = 'whatever'
,
then I get a TypeError: unorderable types: NoneType() < str()
In Py2 it wasn't a problem. How do I handle this in Py3?
sort() doesn't return any value while the sort() method just sorts the elements of a given list in a specific order - ascending or descending without returning any value. So problem is with answer = newList. sort() where answer is none. Instead you can just do return newList.
You cannot unsort the list but you could keep the original unsorted index to restore positions. E.g.
There will be three distinct ways to sort the nested lists. The first is to use Bubble Sort, the second is to use the sort() method, and the third is to use the sorted() method.
The ordering comparison operators are stricter about types in Python 3, as described here:
The ordering comparison operators (<, <=, >=, >) raise a TypeError exception when the operands don’t have a meaningful natural ordering.
Python 2 sorts None
before any string (even empty string):
>>> None < None
False
>>> None < "abc"
True
>>> None < ""
True
In Python 3 any attempts at ordering NoneType
instances result in an exception:
>>> None < "abc"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: NoneType() < str()
The quickest fix I can think of is to explicitly map None
instances into something orderable like ""
:
my_list_sortable = [(x or "") for x in my_list]
If you want to sort your data while keeping it intact, just give sort
a customized key
method:
def nonesorter(a):
if not a:
return ""
return a
my_list.sort(key=nonesorter)
For a general solution, you can define an object that compares less than any other object:
from functools import total_ordering
@total_ordering
class MinType(object):
def __le__(self, other):
return True
def __eq__(self, other):
return (self is other)
Min = MinType()
Then use a sort key that substitutes Min
for any None
values in the list
mylist.sort(key=lambda x: Min if x is None else x)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With