16

因此,当我打印它时,我有一个看起来像这样的字典:

{'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 将不存在。

有任何想法吗?

4

5 回答 5

51

更新了 Python 3.6+ 的答案

>>> d = {'10': -10, 'ZT21': 14, 'WX21': 12, '2': 15, '5': -3, 'UM': -25}
>>> keyorder = ['ZT21', '10', 'WX21', 'UM', '5', '2']
>>> {k: d[k] for k in keyorder if k in d}
{'ZT21': 14, '10': -10, 'WX21': 12, 'UM': -25, '5': -3, '2': 15}

旧版答案:Python 中的字典是无序的(在 Python3.6 之前)。您可以获得所需的结果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如果你做了很多这些,使用 a作为 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)])
于 2012-08-20T02:45:31.520 回答
4

您可以使用 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 中指定的值放在 dict1 中,否则将值设置为 0。

OrderedDict([('monday', 10), ('tuesday', 0), ('wednesday', 34), ('thursday', 12), ('friday', 0), ('saturday', 0)])
于 2018-07-23T05:14:29.860 回答
2

你不能。改用 a collections.OrderedDict

于 2012-08-20T01:57:59.947 回答
1

字典本质上是无序的,所以你不能直接对字典进行排序。您可以通过排序someDict.items()和传递键函数对键/值对进行排序,就像对其他任何内容进行排序一样,但您将获得排序列表而不是字典。请参阅先前有关字典排序的问题:Python:例如对列表进行排序和字典排序按键长度

于 2012-08-20T01:58:18.983 回答
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

于 2014-07-29T20:17:07.173 回答