使用嵌套字典自定义排序 Python 列表
Custom sorting a Python list with nested dictionaries
我正在尝试对代表文件结构的 Python 中的 dictionaries
和 lists
的列表进行排序。我的目标是对列表进行排序,以便所有文件夹(其中包含列表的字典)按字母顺序首先出现。我试着将 运行 排序为 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)
我正在尝试对代表文件结构的 Python 中的 dictionaries
和 lists
的列表进行排序。我的目标是对列表进行排序,以便所有文件夹(其中包含列表的字典)按字母顺序首先出现。我试着将 运行 排序为 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)