我有一个这样的文件名排序列表:
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']
我有一个字典value_dict
:
value_dict = {'val1':[oranges,apples], 'val2':[peaches, grapes, pineapples]}
我已经对列表files
进行了排序,但是我还想根据以下内容对每个值(在本例中为"pkernel"
和val1
)内以val2
结尾的文件进行排序value_dict
中的顺序。因此,"oranges"
在"apples"
的{{1}}之前,并且类似地,我们将使用val1
中指定的顺序。我还有其他扩展名不同于p2kernel的文件,其顺序无需更改。
所以我的value_dict
是
final_list
我试图使用 final_list = ['root/base/val1/oranges/pkernel',
'root/base/val1/apples/pkernel',
'root/base/val1/eng_scope_lattice/p2_kernel',
'root/base/val2/peaches/pkernel',
'root/base/val2/exact_scope_lattice/p2_kernel',
'root/base/val2/grapes/pkernel',
'root/base/val2/pineapple/pkernel']
方法,但是我不知道如何将字典的结果应用于排序子集。因此,我最终使用崇高的文本操作手动完成了此过程。有没有办法使它自动化?
对于p1kernel以外的文件扩展名,原始列表中的顺序应保持不变。
答案 0 :(得分:0)
我不清楚您打算对排序应用什么规则。同样,这种处理方式很容易出错,并且对允许输入的内容进行了很多假设。话虽如此,这几乎可以满足您的要求,只是在示例中,您将列表中的项目放在val 1文件夹而不是val2文件夹的其他项目之前。无论如何,我认为您可以根据此代码使事情正常进行。编辑:修复了代码中的粘贴粘贴错误。
def getKey(val):
for k,v in value_dict.items:
if val.find(k) != -1:
for i in range(len(v)):
val = val.replace(v[i],str(i))
return val
sorted(file, key=getKey)
答案 1 :(得分:0)
是的,有多种方法可以实现此自动化。 我将向您介绍一种非常简单的算法,也许不是最快的算法,但是比使用崇高的文本操作更好。
哪里
def customKeyFunction(path_file):
val_path = path_file[2]
try:
key = value_dict[val_path].index(path_file[3])
except ValueError:
key = -1
return key
sorted(new_list, key=lambda path_file_list: customKeyFunction(path_file_list))
免责声明:这将更改p2kernel文件的顺序。但是与此相关的是您要开始的事情。
答案 2 :(得分:0)
您的问题定义不明确,“顺序不会更改”,因此我假设不存在的键排在开头或结尾。
这里是一种选择:
>>> 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']]