I have the following list of lists of "category"
objects in a variable called "category_tree"
, which is a list:
[[<Category: State>, <Category: County>, <Category: Chicago>],
[<Category: Animal>],
[<Category: State>, <Category: County>],
[<Category: State>, <Category: County>, <Category: NYC>],
[<Category: Animal>, <Category: Fish>],
[<Category: State>, <Category: County>, <Category: LA>],
[<Category: Animal>, <Category: Frog>, <Category: TreeFrog>, <Category: Fred>]]
I need to sort the top-level list
by the .name
properties of the underlying lists
. I do not want to sort the underlying lists, just the top-level list
.
Assuming the .name
elements match what is listed here, this is what I'm trying to get:
[[<Category: Animal>],
[<Category: Animal>, <Category: Fish>],
[<Category: Animal>, <Category: Frog>, <Category: TreeFrog>, <Category: Fred>]
[<Category: State>, <Category: County>],
[<Category: State>, <Category: County>, <Category: Chicago>],
[<Category: State>, <Category: County>, <Category: LA>],
[<Category: State>, <Category: County>, <Category: NYC>]]
I can sort them by the first or the last column with:
category_tree.sort(key=lambda x: x[0].name)
category_tree.sort(key=lambda x: x[-1].name)
But the problem I'm running into is that they have variable numbers of columns, so I can't sort them this way for all internal columns.
What is the best way to do this?
A slighty modified example, with a possible solution:
class Category:
def __init__(self, name):
self.name = name
def __repr__(self):
return self.name
items = [
[Category('State'), Category('County'), Category('Chicago')],
[Category('Animal')],
[Category('State'), Category('County')],
[Category('Animal'), Category('Frog')],
[Category('Animal'), Category('Fish'), Category('Dog')],
]
items.sort(key=lambda x: [item.name for item in x])
print(items)
results in
[[Animal], [Animal, Fish, Dog], [Animal, Frog], [State, County], [State, County, Chicago]]
This relies on the ability of Python to compare lists directly, provided the individual items in the list can be compared properly. For integers, floats and strings, that is not a problem. For a (basic) class, it is, since it not defined by default.
If you have access to the Category
class (ie, you wrote it yourself), you can override __eq__
and other magic comparison methods, which makes things a lot simpler (see eg Compare object instances for equality by their attributes ).
With help from the functools
module:
from functools import total_ordering
@total_ordering
class Category:
def __init__(self, name):
self.name = name
def __eq__(self, other):
return self.name == other.name
def __lt__(self, other):
return self.name < other.name
def __repr__(self):
return self.name
And then simply:
items.sort()
( items
as before).
With the same result: [[Animal], [Animal, Fish, Dog], [Animal, Frog], [State, County], [State, County, Chicago]]
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.