简体   繁体   English

如何在Python中使用字母和数字混合键对字典进行排序?

[英]How to sort a dictionary in Python with keys of mixed letters and numbers?

I have a dictionary like this: 我有一本这样的字典:

dict_str = {'Number_1_item':'foo',
            'Number_11_item':'bar',
            'Number_22_item':'foobar',
            'Number_5_item':'barfoo'}

And my desired out put is: 我想要的输出是:

sorted_dict_str = {'Number_1_item':'foo',
            'Number_5_item':'bar',
            'Number_11_item':'foobar',
            'Number_22_item':'barfoo'}

So the sorted_dict_str is sorted in numerical way based on the keys in dict_str. 因此,sorted_dict_str基于dict_str中的键以数字方式排序。 I have found some answers to sort the keys with pure numeric keys but not mixed ones, so they are not really helpful. 我找到了一些答案,可以用纯数字键而不是混合数字键对键进行排序,因此它们并没有真正的帮助。

Thanks a lot. 非常感谢。

Regards 问候

Yet another solution. 另一个解决方案。 When executing the sorted function it'll return a sorted list of all the keys in the dictionary. 执行排序函数时,它将返回字典中所有键的排序列表。 A dictionary can't be sorted (though there is a way of having an ordered dictionary ). 字典无法排序(尽管有一种有序字典的方式 )。

This Solution is also more robust compared to the first solution, since the number can be anywhere in the key. 与第一个解决方案相比,该解决方案也更健壮,因为数字可以在密钥中的任何位置。

import re
from collections import OrderedDict 

d = {'Number_1_item':'foo',
            'Number_11_item':'bar',
            'Number_22_item':'foobar',
            'Number_5_item':'barfoo'}

keys = d.keys()

def sort_mixed(key):
    int_match = re.search(r'(?P<int>\d+)', key)
    number = int_match.group(0)
    return int(number)

sorted_keys = sorted(keys, key=lambda key: sort_mixed(key))
print(sorted_keys) # print sorted keys

sorted_dict = OrderedDict((k, d[k]) for k in sorted_keys)
print(sorted_dict)  # print new sorted dict

You can get sorted dict from your dict like that: 您可以像这样从字典中获得排序的字典:

from collections import OrderedDict

OrderedDict(sorted(dict_str.items(), key=lambda s: int(s[0].split('_')[1])))

If we can assume that all the keys are on the format Number_XX_item , you could simply sort on the numeric part, using a lambda: 如果我们假设所有键的格式都为Number_XX_item ,则可以使用lambda对数字部分进行排序:

sorted_dict_str = sorted(dict_str.items(), key=lambda x: int(x[0].split('_')[1]))

This gives the following output: 这给出以下输出:

sorted_dict_str = 
[('Number_1_item', 'foo'), 
 ('Number_5_item', 'barfoo'), 
 ('Number_11_item', 'bar'), 
 ('Number_22_item', 'foobar')]

You should check out natsort . 您应该检查一下natsort There are ways to do it by yourself, without importing extra modules, but I like is method. 有很多方法可以自己完成,而无需导入额外的模块,但是我喜欢方法。

>>> from collections import OrderedDict
>>> import natsort

>>> input_dict = {'Number_1_item':'foo', 'Number_11_item':'bar', 'Number_22_item':'foobar', 'Number_5_item':'barfoo'}

>>> OrderedDict(natsort.natsorted(input_dict.items()))

OrderedDict([('Number_1_item', 'foo'), ('Number_5_item', 'barfoo'), ('Number_11_item', 'bar'), ('Number_22_item', 'foobar')])

Here's a solution using the slicing technique I mentioned in the comments. 这是使用我在评论中提到的切片技术的解决方案。 This is less robust than using .split , since the lengths of the prefix & suffix strings are hard-coded, but it's slightly faster because slicing is fast compared to a method call. 与使用.split ,此方法不那么健壮,因为前缀和后缀字符串的长度是硬编码的,但由于与方法调用相比,切片速度更快,因此速度稍快。

from collections import OrderedDict
from pprint import pprint

dict_str = {
    'Number_1_item':'foo',
    'Number_11_item':'bar',
    'Number_22_item':'foobar',
    'Number_5_item':'barfoo',
}

skeys = sorted(dict_str.keys(), key=lambda s: int(s[7:][:-5]))
sorted_dict = OrderedDict((k, dict_str[k]) for k in skeys)
pprint(sorted_dict)

output 输出

OrderedDict([('Number_1_item', 'foo'),
             ('Number_5_item', 'barfoo'),
             ('Number_11_item', 'bar'),
             ('Number_22_item', 'foobar')])

You could also do the sorting on the (key, value) pairs inside the OrderedDict constructor call: 您还可以在OrderedDict构造函数调用内的(键,值)对上进行排序:

sorted_dict = OrderedDict(sorted(dict_str.items(), key=lambda u: int(u[0][7:][:-5])))

but I think my previous version is a little more readable. 但我认为以前的版本更具可读性。

You can't sort the dict itself by definition of what a dict is. 您无法根据字典的定义对字典本身进行排序。 But you can sort its keys in any custom order by passing the desired 'key' argument into sorted function 但是您可以通过将所需的'key'参数传递给已排序的函数来任何自定义顺序对其键进行排序

sorted(iterable[, cmp[, key[, reverse]]]) 排序(iterable [,cmp [,key [,反向]]])

https://docs.python.org/2/library/functions.html#sorted https://docs.python.org/2/library/functions.html#sorted

You can sort the keys of a dictionary into a list, with the additional key-Argument: 您可以将字典的键与其他键参数一起排序到列表中:

dict_str = {'Number_1_item':'foo',
            'Number_11_item':'bar',
            'Number_22_item':'foobar',
            'Number_5_item':'barfoo'}
sorted_keys = sorted(dict_str, key=lambda x: int(x.split('_')[1]))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM