将列表排序为不同的列表
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
.
我有包含 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
.