簡體   English   中英

自定義排序Python字典

[英]Custom Sorting Python Dictionary

所以當我打印它時,我有一個字典看起來像這樣:

{'10': -10, 'ZT21': 14, 'WX21': 12, '2': 15, '5': -3, 'UM': -25}

我想以自定義方式對它們進行排序,我定義了這種方式。 讓我們說我希望它(按鍵)排序的方式是ZT21, 10, WX21, UM, 5, 2

任何人都知道如何以預定義/自定義方式整理字典? 我正在做的是從數據庫中獲取這個字典,它可以提供超過20個密鑰,所有密鑰都有特定的順序。 始終設置順序,但有時某些鍵/值不會出現在字典中。 所以這也可能發生:

{'ZT21': 14, 'WX21': 12, '2': 15, '5': -3, 'UM': -25}

排序(按鍵)是ZT21, 10, WX21, UM, 5, 2

所以10在這個例子中不存在,但我需要的排序仍然是相同的,10只是不存在。

有任何想法嗎?

Python中的字典是無序的。 您可以將所需的結果作為list

>>> d = {'10': -10, 'ZT21': 14, 'WX21': 12, '2': 15, '5': -3, 'UM': -25}
>>> keyorder = ['ZT21', '10', 'WX21', 'UM', '5', '2']
>>> sorted(d.items(), key=lambda i:keyorder.index(i[0]))
[('ZT21', 14), ('10', -10), ('WX21', 12), ('UM', -25), ('5', -3), ('2', 15)]

或者作為OrderedDict

>>> from collections import OrderedDict
>>> OrderedDict(sorted(d.items(), key=lambda i:keyorder.index(i[0])))
OrderedDict([('ZT21', 14), ('10', -10), ('WX21', 12), ('UM', -25), ('5', -3), ('2', 15)])

如果你正在做很多這樣的事情,那么使用dict作為keyorder會更有效率

>>> keyorder = {k:v for v,k in enumerate(['ZT21', '10', 'WX21', 'UM', '5', '2'])}
>>> OrderedDict(sorted(d.items(), key=lambda i:keyorder.get(i[0])))
OrderedDict([('ZT21', 14), ('10', -10), ('WX21', 12), ('UM', -25), ('5', -3), ('2', 15)])

你不能。 請改用collections.OrderedDict

字典本質上是無序的,因此您無法直接對字典進行排序。 您可以通過排序someDict.items()並傳入一個鍵函數來對鍵/值對進行排序,就像排序其他任何內容一樣,但是您將獲得一個排序列表而不是字典。 請參閱有關字典排序的先前問題: Python:按列 長度排序 列表按密鑰長度排序字典

您可以使用OrderedDict並通過指定自定義順序對其進行排序。

def customsort(dict1 , key_order):
    items = [dict1[k] if k in dict1.keys() else 0 for k in key_order] 
    sorted_dict = OrderedDict()
    for i in range(len(key_order)):
        sorted_dict[key_order[i]] = items[i]
    return sorted_dict
key_order = [ "monday" ,"tuesday" ,"wednesday" ,"thursday" ,"friday" ,"saturday"]
dict1 ={"monday" : 10 , "thursday" :12 , "wednesday" : 34}
sorted_dicti = customsort(dict1,key_order)
print(sorted_dicti)

customsort()按用戶傳遞的order(key_order)對字典(dict1)進行排序。

items = [dict1[k] if k in dict1.keys() else 0 for k in key_order] 

它將檢查給定的密鑰是否在dict1中,如果它在那里然后放入在dict1中指定的值,否則將值設置為0。

OrderedDict([('monday', 10), ('tuesday', 0), ('wednesday', 34), ('thursday', 12), ('friday', 0), ('saturday', 0)])

我有完全相同的問題,並設計了一個輕量級的通用解決方案:

from collections import OrderedDict

def make_custom_sort(orders):
    orders = [{k: -i for (i, k) in enumerate(reversed(order), 1)} for order in orders]
    def process(stuff):
        if isinstance(stuff, dict):
            l = [(k, process(v)) for (k, v) in stuff.items()]
            keys = set(stuff)
            for order in orders:
                if keys.issuperset(order):
                    return OrderedDict(sorted(l, key=lambda x: order.get(x[0], 0)))
            return OrderedDict(sorted(l))
        if isinstance(stuff, list):
            return [process(x) for x in stuff]
        return stuff
    return process

首先,創建自定義順序排序函數的實例:

custom_sort = make_custom_sort([ ['ZT21', '10', 'WX21', 'UM', '5', '2'] ])

現在,實際排序:

result = custom_sort(my_dataset)

丟失的密鑰最后以未指定的順序被拒絕。 請注意,此閉包是遞歸的。 如雙括號所示,您可以指定與您的結構中嵌套的各種字典所需的排序順序一樣多。

GitHub項目: https//github.com/laowantong/customsort

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM