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

2024-10-03 17:18:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个文件名的排序列表,如下所示:

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进行了排序,但是我还想根据value_dict中的顺序对每个值(val1val2)中以"pkernel"结尾的文件进行排序。因此"oranges"将在"apples"之前出现在val1的前面,同样,我们将使用value_dict中指定的顺序。我还有其他扩展名不同于p2kernel的文件,它们的顺序不需要更改

所以我的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']

我试图使用sorted(s, key = operator.itemgetter(1, 2))方法,但我不知道如何在排序子集中应用字典的结果。因此,我最终使用升华文本操作手动执行此过程。有没有一种方法可以让这一切自动化

对于p1kernel以外的文件扩展名,原始列表中的顺序应保持不变


Tags: base排序顺序valuerootkerneldictscope
3条回答

我很不清楚您打算对排序应用什么规则。同样,这种方法也很老套,并且对允许输入的内容做了很多假设。这就是说,这几乎满足了您的要求,除了在您的示例中,您将列表中的项目放在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. 将文件数组转换为数组,我的意思是对每个字符串使用split(“/”),以便在列表中转换它们
  2. 您可以使用排序(新列表,key=lambda路径文件列表:customKeyFunction(路径文件列表))

在哪里

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))

免责声明:这将更改内核文件的顺序。但有了这个,你就有了开始

您的问题定义错误,带有“顺序不会更改”,因此我将假定不存在的键按开头或结尾排序

这里有一个选择:

>>> 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

我们必须做一些傻事,因为Python 3不允许在字符串列表中间粘贴,例如^ {CD2>},并以表格

比较它们。
[['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']]

相关问题 更多 >