如何对Python OrderedDict的所有级别进行排序

时间:2014-08-27 17:34:34

标签: python sorting dictionary

我正在尝试按密钥字符串长度(从最长到最短)对Python有序字典的所有级别进行排序。在我看来,这意味着转换它:

{
    "Scientology": {
        "source": "LRH",
        "scilon 1": {
            "name": "John Travolta",
            "OT level": 5,
            "wall of fire": True
        },
        "scilon 2": {
            "name": "Tom Cruise",
            "OT level": 6,
            "wall of fire": True
        }
    }
}

到此:

{
    "Scientology": {
        "scilon 1": {
            "wall of fire": True,
            "OT level": 5,
            "name": "John Travolta"
        },
        "scilon 2": {
            "wall of fire": True,
            "OT level": 6,
            "name": "Tom Cruise"
        },
        "source": "LRH",
    }
}

目前,这是我的代码:

dictionary1 = {
    "Scientology": {
        "source": "LRH",
        "scilon 1": {
            "name": "John Travolta",
            "OT level": 5,
            "wall of fire": True
        },
        "scilon 2": {
            "name": "Tom Cruise",
            "OT level": 6,
            "wall of fire": True
        }
    }
}

from collections import OrderedDict
print(OrderedDict(sorted(dictionary1.items(), key = lambda t: len(t[0]))))

这会产生以下输出:

OrderedDict([('Scientology', {'scilon 2': {'OT level': 6, 'name': 'Tom Cruise', 'wall of fire': True}, 'source': 'LRH', 'scilon 1': {'OT level': 5, 'name': 'John Travolta', 'wall of fire': True}})])

这似乎没有按我的意愿排序。我怎么能按照我描述的方式对有序字典进行排序?

1 个答案:

答案 0 :(得分:2)

如果你想对所有项目进行排序,似乎递归是最好的方法:

def _sort_fn(key_value_pair):
    key, value = key_value_pair
    # negative len -- Longer keys will show up first.
    # also add `key` to the tuple as keys with same length get sorted lexicographically.
    return -len(key), key

def sort_dict(d):
    new_dict = collections.OrderedDict()
    for k, v in sorted(d.items(), key=_sort_fn):
        if isinstance(v, dict):
            new_dict[k] = sort_dict(v)
        else:
            new_dict[k] = v
    return new_dict

在输入中使用此功能:

>>> import json  # pprint doesn't handled OrderedDict :-(
>>> print json.dumps(sort_dict(dictionary1), indent=4)
{
    "Scientology": {
        "scilon 1": {
            "wall of fire": true, 
            "OT level": 5, 
            "name": "John Travolta"
        }, 
        "scilon 2": {
            "wall of fire": true, 
            "OT level": 6, 
            "name": "Tom Cruise"
        }, 
        "source": "LRH"
    }
}