在Python中对异构对象列表进行排序
我有一些自定义的对象和字典,我想把它们排序。我想把对象和字典一起排序。对象是根据某个属性来排序,而字典是根据一个键来排序。
object.name = 'Jack'
d = {'name':'Jill'}
sort_me =[object, d]
我该如何使用对象的名称属性和字典的“名称”键来排序这个列表呢?
4 个回答
1
这个方法对我有效。需要注意的是,sort()
这个函数不会返回一个排序好的列表,而 sorted()
会返回一个排序好的列表。所以如果你想把这个列表传给模板,你应该在参数中使用 sorted
,或者在传递列表作为参数之前先用 sort
排序。
itemized_action_list = list(chain(detection_point.insertbodyaction_set.all(),
detection_point.insertheaderaction_set.all(),
detection_point.modifybodyaction_set.all(),
detection_point.modifyheaderaction_set.all(),
detection_point.removebodyaction_set.all(),
detection_point.removeheaderaction_set.all(),
detection_point.redirectaction_set.all()))
sorted(itemized_action_list, key=attrgetter('priority'))
3
sort_me.sort(key=attr_or_itemgetter('name'))
这里的 attr_or_itemgetter()
是一个函数:
class attr_or_itemgetter(object):
def __init__(self, name):
self.name = name
def __call__(self, obj):
try: return getattr(obj, name)
except AttributeError:
return obj[name]
注意:这个函数故意不检查输入是不是字典类型,所以当你对一个字典使用 attr_or_itemgetter('items')
时,它会返回 dict.items
这个方法。
8
你可能想要的是使用 sorted() 函数中的 key= 选项,这个选项可以让你提供一个函数,这个函数会为每个元素返回一个排序的关键字。这个函数可以检查它接收到的参数类型,并根据不同的类型采取不同的操作。例如:
import types
class obj(object):
def __init__(self, arg):
self.name = arg
def extract_name(obj):
if type(obj) is types.DictType:
return obj['name']
else:
return obj.__dict__['name']
d = { 'name': 'Jill'}
print sorted([obj('Jack'), d], key=extract_name)
想了解更多信息,可以去 Python wiki 查看。
RichieHindle 提出的使用 isinstance 的建议很好。而且我想,支持任意元素名称而不是死板地写 'name' 也不错:
def extract_elem_v2(elem_name):
def key_extractor(obj):
dct = obj if isinstance(obj, dict) else obj.__dict__
return dct[elem_name]
return key_extractor
你可以这样使用:
print sorted(list_of_stuff, key=extract_elem_v2('name'))