我有一个字符串模板,我想从中生成文件名。它现在使用带有命名占位符的百分比格式,并且可以有任意数量的要替换的部分。
template = "image_%(uval)02d_%(vval)02d.%(frame)04d.tif"
我有一个包含占位符键和值列表的对象:
params = {
"uval": [1,2],
"vval": [1,2],
"frame": [10,11]
}
我想用格式生成排列:
[
"image_01_01.0010.tif",
"image_01_01.0011.tif",
"image_01_02.0010.tif",
"image_01_02.0011.tif",
"image_02_01.0010.tif",
"image_02_01.0011.tif",
"image_02_02.0010.tif",
"image_02_02.0011.tif"
]
所以我尝试了这个:
def permutations(template, params):
# loop through params, each time replacing expanded with the
# new list of resolved filenames.
expanded = [template]
for param in params:
newlist = []
for filename in expanded:
for number in params[param]:
newlist.append(filename % {param: number})
expanded = newlist
return expanded
print permutations(template, params)
问题是:
newlist.append(filename % {param: number})
KeyError: 'uval'
由于它一次替换一个键,因此每次迭代中只存在一个占位符,因此不存在的占位符会导致错误。理想情况下,在更换一个密钥时,它应该保持模板的其余部分不受影响。
如果当然只有一个占位符,它可以正常工作:
template = "image.%(frame)04d.tif"
params = {"frame": [10, 11]}
print permutations(template, params)
Result: ['image.0010.tif', 'image.0011.tif']
我不介意使用其他系统,但理想情况下我希望模板字符串具有表现力且易于推理。
欢迎提示
答案 0 :(得分:3)
我使用itertools.product
来选择参数,并为每个组合构建一个字典,以便在格式化步骤中使用,该步骤一次性替换所有占位符:
import itertools
def permutations(template, params):
for vals in itertools.product(*params.values()):
substituion_dict = dict(zip(params, vals))
yield template % substituion_dict
这是一个生成器函数,因此它返回一个迭代器而不是结果列表。要打印它,您需要先将迭代器传递给list
。但是,如果您的真实代码要执行其他操作(例如在for
循环中循环结果,对每个循环执行某些操作),您可能根本不需要创建列表。您可以直接从生成器函数循环迭代器。