将列表排序为不同的列表

Sort List into different lists

我有包含 file_names 的列表。 (约 800 file_names)

[示例] file_name = 23475048_43241u_43x_pos11_7.npz

我需要对 file_names 进行排序并将其添加到列表中。 file_names 按“位置”排序。在我的示例中是 pos11。 (有不同的pos -> pos0, pos12...)

我首先尝试在字典中获取所有不同的 pos_numbers:

path =[filename for filename in glob.glob(os.path.join(my_dir, '*.npz'))] 

posList = []

for file in path:
  file_name = Path(file).parts[-1][:-4].split("_")
  posList.append(file_name[3])

mylist =  list(dict.fromkeys(posList))
files_dict = {}
for pos in mylist:files_dict[pos] = []

输出:

{'pos0': [], 'pos10': [], 'pos11': [], 'pos12': [], 'pos1': [], 'pos2': [], 'pos3': [], 'pos4': [], 'pos5': [], 'pos6': [], 'pos7': [], 'pos8': [], 'pos9': []}

现在我想填写不同的列表。但现在我卡住了。我想用 file_names 再次遍历列表并将它们添加到右列表中。

不确定你的代码在做什么,但你可以使用下面的程序,它接收文件名列表并输出由 pos 索引的排序列表的字典,我认为你正在尝试这样做。 (如果不是,也许可以编辑您的问题以详细说明)

files = ['1_2_3_pos1_2.np', '2_3_1_pos2_2.npz']
files_dict = {}
for file in files:
    pos = file.split('_')[3]
    files_dict[pos] = files_dict.get(pos, []) + [file]

for k in files_dict.keys():
    files_dict[k].sort()

print(files_dict)

编辑: 正如@Stef 建议的那样,您可以使用 setdefault

使其更有效
files = ['1_2_3_pos1_2.np', '2_3_1_pos2_2.npz']
files_dict = {}
for file in files:
    pos = file.split('_')[3]
    files_dict.setdefault(pos, []).append(file)

for k in files_dict.keys():
    files_dict[k].sort()

print(files_dict)

您需要在 pos 使用正则表达式 (\d+)_\d\.npz 之后提取数字,然后使用 .sort() 函数

import re

posList = '''23475048_43241u_43x_pos11_7.npz
23475048_43241u_43x_pos1_7.npz
23475048_43241u_43x_pos10_7.npz
23475048_43241u_43x_pos8_7.npz
23475048_43241u_43x_pos22_7.npz
23475048_43241u_43x_pos2_7.npz'''.split("\n")


posList = sorted(posList, key=lambda x: int(re.search(r"(\d+)_\d\.npz", x)[1]))
print(posList)

结果

['23475048_43241u_43x_pos1_7.npz',
  '23475048_43241u_43x_pos2_7.npz',
  '23475048_43241u_43x_pos8_7.npz',
  '23475048_43241u_43x_pos10_7.npz',
  '23475048_43241u_43x_pos11_7.npz',
  '23475048_43241u_43x_pos22_7.npz'
]

@ARandomDeveloper 的回答清楚地解释了如何通过仅遍历列表一次来填充字典。我建议您研究他们的答案,直到您完全理解为止。

这是一种非常常见的填充字典的方法。你可能会再次遇到这种模式。

因为这种分组成字典的操作很常见,module more_itertools offers a function map_reduce正是为了这个目的。

from more_itertools import map_reduce

posList = '''23475048_43241u_43x_pos11_7.npz
23475048_43241u_43x_pos1_7.npz
23475048_43241u_43x_pos10_7.npz
23475048_43241u_43x_pos8_7.npz
23475048_43241u_43x_pos22_7.npz
23475048_43241u_43x_pos2_7.npz'''.split("\n") # example list from uingtea's answer

d = map_reduce(posList, keyfunc=lambda f: f.split('_')[3])

print(d)
# defaultdict(None, {
#   'pos11': ['23475048_43241u_43x_pos11_7.npz'],
#   'pos1': ['23475048_43241u_43x_pos1_7.npz'],
#   'pos10': ['23475048_43241u_43x_pos10_7.npz'],
#   'pos8': ['23475048_43241u_43x_pos8_7.npz'],
#   'pos22': ['23475048_43241u_43x_pos22_7.npz'],
#   'pos2': ['23475048_43241u_43x_pos2_7.npz']
# })

Internally, map_reduce uses almost-exactly the same code as suggested in @ARandomDeveloper's answer, except with a defaultdict.