Ваш вопрос неверно определен с "порядок не будет изменен", поэтому я предполагаю, что отсутствующие ключи отсортированы в начало или конец.
Вот один из вариантов:
>>> sorted(files, key=sort_order)
['root/base/val1/eng_scope_lattice/p2_kernel',
'root/base/val1/oranges/pkernel',
'root/base/val1/apples/pkernel',
'root/base/val2/exact_scope_lattice/p2_kernel',
'root/base/val2/pineapple/pkernel',
'root/base/val2/peaches/pkernel',
'root/base/val2/grapes/pkernel']
где мы определяем sort_order
следующим образом:
import math
files = [
'root/base/val1/apples/pkernel',
'root/base/val1/oranges/pkernel',
'root/base/val1/eng_scope_lattice/p2_kernel',
'root/base/val2/grapes/pkernel',
'root/base/val2/exact_scope_lattice/p2_kernel',
'root/base/val2/peaches/pkernel',
'root/base/val2/pineapple/pkernel'
]
_orders = {
'val1': ['oranges', 'apples'],
'val2': ['peaches', 'grapes', 'pineapples']
}
orders = {k: {val: ind for ind, val in enumerate(v)} for k, v in _orders.items()}
digits = {k: int(math.ceil(math.log(len(v), 10))) for k, v in orders.items()}
BASE = ['root', 'base']
def sort_order(file):
fragments = file.split('/')
if fragments[:2] == BASE:
if len(fragments) > 3:
folder, subfolder = fragments[2:4]
if folder in orders:
index = orders[folder].get(subfolder, '') # Put unknown first
str_index = index and f'{index:0{digits[folder]}d}'
fragments[3] = f'{str_index}/{subfolder}'
return fragments
Нам приходится делать глупые вещи, потому что python3 не позволяет вставлять, например, (1, 'foo')
в середине списка строк. и сравнивая их, в виде
[['root', 'base', 'val1', '1/apples', 'pkernel'],
['root', 'base', 'val1', '0/oranges', 'pkernel'],
['root', 'base', 'val1', '/eng_scope_lattice', 'p2_kernel'],
['root', 'base', 'val2', '1/grapes', 'pkernel'],
['root', 'base', 'val2', '/exact_scope_lattice', 'p2_kernel'],
['root', 'base', 'val2', '0/peaches', 'pkernel'],
['root', 'base', 'val2', '/pineapple', 'pkernel']]