2009-10-10 36 views
5

Tôi có một số từ điển và từ điển tùy chỉnh mà tôi muốn sắp xếp. Tôi muốn sắp xếp cả hai đối tượng từ điển cùng nhau. Tôi muốn sắp xếp các đối tượng bằng một thuộc tính và từ điển bằng một khóa.Sắp xếp danh sách đối tượng không đồng nhất trong Python

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

sort_me =[object, d] 

Làm cách nào để sắp xếp danh sách này bằng thuộc tính tên của đối tượng và phím 'tên' của từ điển?

Trả lời

8

Điều bạn gần như chắc chắn đang tìm kiếm là sử dụng tùy chọn key = cho sắp xếp(), cung cấp hàm trả về khóa sắp xếp tùy ý cho mỗi phần tử. Hàm này có thể kiểm tra kiểu đối số của nó và thực hiện các hành động khác nhau. Ví dụ:

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) 

Thông tin thêm có thể được tìm thấy trên gợi ý của việc sử dụng isinstance các Python wiki

RichieHindle là một tốt nhất. Và trong khi tôi đã ở đó tôi nghĩ nó có thể là tốt đẹp để hỗ trợ các tên phần tử tùy ý thay vì hardcoding '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 

Mà bạn có thể sử dụng như sau:

print sorted(list_of_stuff, key=extract_elem_v2('name')) 
+3

+1. Đề xuất nhỏ: 'isinstance (obj, dict)' sẽ là neater, và sẽ cho phép các lớp bắt nguồn từ 'dict'. – RichieHindle

+0

Bạn nói đúng, isinstance là một lựa chọn tốt hơn ở đó, không chắc tại sao tôi không nghĩ về điều đó. Phiên bản cập nhật được thêm vào câu trả lời. Cảm ơn! –

+0

Cảm ơn rất nhiều Jack! Câu trả lời này rất đẹp. Thuộc tính – hekevintran

2
sort_me.sort(key=attr_or_itemgetter('name')) 

đâu 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] 

LƯU Ý: Chủ định không kiểm tra loại từ điển, do đó attr_or_itemgetter('items') áp dụng cho một từ điển sẽ trả về phương pháp dict.items.

+1

Tôi tìm thấy câu trả lời này nhiều hơn Pythonic so với loại dựa trên kiểm tra kiểu (có thể chậm hơn một chút nếu có nhiều dicts trong chuỗi đang được sắp xếp, nhưng tất cả phải mất để tối ưu hóa nó cho sử dụng đó là lật cơ thể cố gắng là gì và ngoại trừ cơ thể là gì, và bắt các ngoại lệ khác nhau; -0). –

1

Điều này phù hợp với tôi. Lưu ý rằng sort() không trả về danh sách đã sắp xếp, nhưng sorted() có, vì vậy nếu bạn muốn chuyển mẫu này vào mẫu, bạn nên sử dụng sorted trong tham số hoặc sort trước khi bạn chuyển danh sách làm tham số.

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

Chào mừng bạn đến với SO. Cố gắng rõ ràng và chính xác trong ví dụ của bạn. Không có thông tin bổ sung, bạn không thể nói danh sách của mình chứa gì. – joaquin

Các vấn đề liên quan