使用嵌套字典自定义排序 Python 列表

Custom sorting a Python list with nested dictionaries

我正在尝试对代表文件结构的 Python 中的 dictionarieslists 的列表进行排序。我的目标是对列表进行排序,以便所有文件夹(其中包含列表的字典)按字母顺序首先出现。我试着将 运行 排序为 KeyError。有人有推荐的解决方案吗?

这是我目前拥有的:

[
    {
        'file_name': 'abc.txt',
        'endpoint': '/code/d20cb114-b68c-11ec-b468-a063919f3f30/abc.txt'
    }, 
    {
        'src': [
            {
                'file_name': 'jump.sql',
                'endpoint': '/code/d20cb114-b68c-11ec-b468-a063919f3f30/jump.sql'
            },
            {
                'file_name': 'test.txt',
                'endpoint': '/code/d20cb114-b68c-11ec-b468-a063919f3f30/test.txt'
            },
            {
                'file_name': 'tester.txt',
                'endpoint': '/code/d20cb114-b68c-11ec-b468-a063919f3f30/tester.txt'
            }
        ]
    },
    {
        'test': [
            {
                'file_name': 'test.java',
                'endpoint': '/code/d20cb114-b68c-11ec-b468-a063919f3f30/test.java'
            },
            {
                'file_name': 'testerjunit.cpp',
                'endpoint': '/code/d20cb114-b68c-11ec-b468-a063919f3f30/testerj.cpp'
            }
        ]
    },
    {
        'file_name': 'test.log',
        'endpoint': '/code/d20cb114-b68c-11ec-b468-a063919f3f30/test.log'
    }
]

这就是我想要的排序输出:

[
    {
        'src': [
            {
                'file_name': 'jump.sql',
                'endpoint': '/code/d20cb114-b68c-11ec-b468-a063919f3f30/jump.sql'
            },
            {
                'file_name': 'test.txt',
                'endpoint': '/code/d20cb114-b68c-11ec-b468-a063919f3f30/test.txt'
            },
            {
                'file_name': 'tester.txt',
                'endpoint': '/code/d20cb114-b68c-11ec-b468-a063919f3f30/tester.txt'
            }
        ]
    },
    {
        'test': [
            {
                'file_name': 'test.java',
                'endpoint': '/code/d20cb114-b68c-11ec-b468-a063919f3f30/test.java'
            },
            {
                'file_name': 'testerjunit.cpp',
                'endpoint': '/code/d20cb114-b68c-11ec-b468-a063919f3f30/testerj.cpp'
            }
        ]
    },
    {
        'file_name': 'abc.txt',
        'endpoint': '/code/d20cb114-b68c-11ec-b468-a063919f3f30/abc.txt'
    }, 
    {
        'file_name': 'test.log',
        'endpoint': '/code/d20cb114-b68c-11ec-b468-a063919f3f30/test.log'
    }
]

我尝试使用 lambda 函数按键 file_name 进行排序,但这给了我一个 KeyError 因为键不直接在每个 dict.[=21 中=]

res.sort(key=lambda e: e['file_name'], reverse=True)

其中 res 是列表对象。

有人知道执行此操作的更好方法吗?

TIA!

您可以执行以下操作:

folders, files = [], []

for obj in res:
    if len(obj) == 1:
        folders.append(obj)
    else:
        files.append(obj)

folders.sort(key=lambda e: next(iter(e.keys())))
files.sort(key=lambda e: e['file_name'])
res = folders + files

此代码只是将对象分成两个单独的列表(其中假定表示文件夹的每个条目都是长度为 1 的对象),然后分别对两个列表进行排序,最后将它们连接起来。文件夹列表根据字典(文件夹对象)中单个条目的键(文件夹名称)进行排序。请注意,此方法还会对不在文件夹中的文件进行排序,这可以通过删除行 files.sort(key=lambda e: e['file_name'])) 轻松避免。另请注意,这不会对文件夹内的文件进行排序,这可以通过添加以下代码来实现:

for folder in folders:
    folder_name, file_names = next(iter(folder.items()))
    folder[folder_name] = sorted(file_names, key=lambda e: e['file_name'])

编辑:以下函数将所有这些放在一起,还允许任意嵌套级别:

def sort_objects(objects):
    folders = list(filter(lambda o: len(o) == 1, objects))
    files = list(filter(lambda o: len(o) != 1, objects))
    for folder in folders:
        name, inner_objects = next(iter(folder.items()))
        folder[name] = sort_objects(inner_objects)
    sorted_folders = sorted(folders, key=lambda e: next(iter(e.keys())))
    sorted_files = sorted(files, key=lambda e: e['file_name'])
    return sorted_folders + sorted_files
    
res = sort_objects(res)