2009-10-10 17 views
5

我有一些自定义对象和字典,我想排序。我想将这两个字典的字典排在一起。我想通过属性和字典按键排序对象。在Python中排序对象的异类列表

object.name = 'Jack' 
d = {'name':'Jill'} 

sort_me =[object, d] 

如何使用对象的名称属性和字典的'名称'键对此列表进行排序?

回答

8

你几乎可以肯定地寻找的是对sorted()使用key =选项,它提供了一个函数,它为每个元素返回一个任意的排序键。该函数可以检查其参数的类型并采取各种行动。例如:可以使用isinstance的Python wiki

RichieHindle的建议中找到

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) 

更多信息是一个很好的一个。虽然我在这我想这可能是不错的支持,而不是硬编码“姓名”任意元素名称:

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')) 
+3

+1。小提示:'isinstance(obj,dict)'会更整洁,并且允许从'dict'派生类。 – RichieHindle

+0

你是对的,isinstance是一个更好的选择,不知道为什么我没有想到这一点。更新版本附加到答案。谢谢! –

+0

非常感谢杰克!这个答案很美。 – hekevintran

2
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] 

注意:它故意不检查字典类型,因此应用于字典的将返回dict.items方法。

+1

我发现这个答案比基于类型检查的更加Pythonic(如果序列中有大量字典被排序,可能会稍微慢一点,但是所有这些都需要优化它这个用法是翻转什么是try body和除body之外的东西,并捕捉不同的例外; -0)。 –

1

这对我有效。请注意,sort()不会返回排序列表,但sorted()会这样做,因此如果要将此内容传递给模板,则应在参数或sort中使用sorted,然后再将该列表作为参数传递。

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')) 
+0

欢迎来到SO。试着在你的例子中清楚准确。没有其他信息,不可能说出你的列表包含什么。 – joaquin