[英]Sorting file names in a list based on order from another list/dictionary
I have a sorted list of filenames given like this:我有一个排序的文件名列表,如下所示:
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']
and I have a dictionary value_dict
:我有一个字典
value_dict
:
value_dict = {'val1':[oranges,apples], 'val2':[peaches, grapes, pineapples]}
I have sorted the list files
but I also want to sort the files that end with "pkernel"
inside each value ( val1
and val2
in this case) based on the order in the value_dict
.我已经对列表
files
进行了排序,但我还想根据 value_dict 中的顺序对每个值(在本例中为val1
和val2
)内以"pkernel"
value_dict
的文件进行排序。 So "oranges"
will come before "apples"
for val1
and similarly we will use the order specified in value_dict
.因此对于
val1
, "oranges"
将出现在"apples"
之前,同样我们将使用value_dict
中指定的顺序。 I also have other files with extensions different than p2kernel whose order does not need to be changed.我还有其他扩展名不同于 p2kernel 的文件,它们的顺序不需要更改。
So my final_list
will be所以我的
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']
I was trying to use the sorted(s, key = operator.itemgetter(1, 2))
methods but I don't know how to apply the results of the dictionary in subsets of sorting.我试图使用
sorted(s, key = operator.itemgetter(1, 2))
方法,但我不知道如何在排序子集中应用字典的结果。 So I end up doing this process manually using sublime text operations.所以我最终使用 sublime text 操作手动完成这个过程。 Is there a way to automate this?
有没有办法自动化这个?
For file extensions other than p1kernel the order in the original list should stay intact.对于 p1kernel 以外的文件扩展名,原始列表中的顺序应保持不变。
It is very unclear to me exactly what rules you intend to apply to the sorting.我不清楚您打算将哪些规则应用于排序。 Also this way of doing things is pretty hack-y and makes a lot of assumptions about what your inputs are allowed to look like.
此外,这种做事方式非常hack-y,并且对您的输入允许的外观做出了很多假设。 That being said this almost does what you ask except in your example you put items from the lists before other items for the val 1 folder but not the val2 folder.
话虽如此,这几乎可以满足您的要求,除了在您的示例中,您将列表中的项目放在 val 1 文件夹而不是 val2 文件夹的其他项目之前。 Anyway I think you aught to be able to make things work based on this code.
无论如何,我认为您应该能够根据此代码使事情正常进行。 Edited: fixed copy paste error in the code.
编辑:修复了代码中的复制粘贴错误。
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)
Yes, there is more than a way to automate this.是的,有不止一种方法可以自动执行此操作。 I will explain you one very simple algorithm, maybe not the fastest but it's better than using sublime text operations.
我将向您解释一种非常简单的算法,可能不是最快的,但它比使用 sublime 文本操作要好。
Where在哪里
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))
Disclaimer: this will change the order of the p2kernel files.免责声明:这将改变 p2kernel 文件的顺序。 But with this you have something to start from.
但是有了这个,你就有了开始的地方。
Your question is ill-defined with "order will not be changed", so I will assume that keys not present are sorted to the beginning or the end.您的问题定义不明确,“顺序不会改变”,所以我假设不存在的键被排序到开头或结尾。
Here is one option:这是一种选择:
>>> 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']
where we define sort_order
as follows:我们定义
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
We have to do silly things because python3 doesn't allow sticking eg (1, 'foo')
in the middle of a list of strings and comparing them, in the form我们必须做一些愚蠢的事情,因为 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']]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.