简体   繁体   English

根据来自另一个列表/字典的顺序对列表中的文件名进行排序

[英]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 中的顺序对每个值(在本例中为val1val2 )内以"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 文本操作要好。

  1. Transform your array of files to an array of arrays, I mean use split("/") on each string in order to convert them on a list.将文件数组转换为 arrays 数组,我的意思是在每个字符串上使用 split("/") 以便将它们转换为列表。
  2. You can use sorted(new_list, key=lambda path_file_list: customKeyFunction(path_file_list))您可以使用 sorted(new_list, key=lambda path_file_list: customKeyFunction(path_file_list))

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM