2009-10-10 6 views
5

정렬 할 사용자 정의 객체 및 사전이 있습니다. 나는 두 사전 모두 함께 개체를 정렬 싶어요. 나는 속성에 의한 객체와 사전에 의한 키를 정렬하고 싶다.Python에서 이기종 객체 목록 정렬

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

sort_me =[object, d] 

개체의 이름 속성과 사전의 '이름'키를 사용하여이 목록을 어떻게 정렬합니까?

답변

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) 

상세 정보 isinstance를 사용하는 Python wiki

RichieHindle의 제안에서 찾을 수 있습니다 좋은 하나입니다.

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] 

참고 : 의도적으로 사전 유형을 확인하지 않으므로 attr_or_itemgetter('items') 사전에 적용하면 dict.items 메서드가 반환됩니다.

+1

이 답변은 형식 검사를 기반으로하는 Pythonic보다 더 Pythonic입니다 (순서에 많은 dicts가 정렬되어 있으면 조금 느려질 수 있지만 그 사용은 try body와 except body 인 것을 뒤집어 놓고 다른 예외를 잡는다; -0). –

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

안녕하세요. 당신의 예에서 명확하고 정확한 것을 시도하십시오. 추가 정보없이 귀하의 목록에 무엇이 포함되어 있는지 말할 수 없습니다. – joaquin