Python 简化动态列表中字符串的修改?
我想将字符串列表从一种格式更改为另一种格式 可在此处找到完整列表的示例: 我正在尝试做的一些例子:Python 简化动态列表中字符串的修改?,python,string,replace,split,Python,String,Replace,Split,我想将字符串列表从一种格式更改为另一种格式 可在此处找到完整列表的示例: 我正在尝试做的一些例子: Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 致: 这是: Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)) 为此: (8): Conv2d(64 -> 128, 3x3, 1,1, 1,1) 我当前的代码设置如下所示:
Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
致:
这是:
Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
为此:
(8): Conv2d(64 -> 128, 3x3, 1,1, 1,1)
我当前的代码设置如下所示:
def modify_text(text, new):
return text.replace(", ","*", 1).replace(", ", new, 1)
for i, layer in enumerate(net):
if "Conv2d" in str(layer):
layer = str(layer).replace(","," ->", 1)
layer = modify_text(layer, "x").replace("kernel_size=(", "").replace("stride=(", "").replace("padding=(", "").replace(")","", 3)
layer = modify_text(modify_text(layer, ","), ",").replace("*",", ")
print(" (" + str(i+1) + "): " + layer)
但我觉得有一种更美观/更简单的方法可以做到这一点
编辑,我已将设置简化为:
regx_map = r'(2d).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*'
regx_pool = r'(2d).*?(\d+).*?(\d+).*?(\d+).*'
for i, layer in enumerate(net):
if "Conv2d" in str(layer):
print(" (" + str(i+1) + "): " + re.sub(regx_map, r'\1(\2 -> \3, \4x\5, \6,\7, \8,\9)', str(layer)))
elif "MaxPool2d" in str(layer) or "AvgPool2d" in str(layer):
print(" (" + str(i+1) + "): " + re.sub(regx_pool, r'\1(\2x\2, \3,\3)', str(layer)))
else:
print(" (" + str(i+1) + "): " + "nn." + str(layer).split("(", 1)[0])
您可以使用正则表达式来匹配:
import re
s = 'Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))'
regx = r'(Conv2d).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*'
print(re.sub(regx, r'\1(\2 -> \3, \4x\5, \6,\7,\8,\9)', s))
输出:
Conv2d(3 -> 64, 3x3, 1,1,1,1)
['TVLoss()', 'Conv2d(3 -> 64, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(64 -> 64, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(64 -> 128, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(128 -> 128, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(128 -> 256, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(256 -> 256, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'Conv2d(256 -> 256, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'Conv2d(256 -> 256, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(256 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(512 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'ContentLoss((crit): MSELoss())', 'Conv2d(512 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'Conv2d(512 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(512 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())']
如果您想让regex稍微更加健壮,但代价是它相当长:
(Conv2d)\((\d+),\s(\d+),\skernel_size=\((\d+),\s(\d+)\),\sstride=\((\d+),\s(\d+)\),\spadding=\((\d+),\s(\d+)\)\)
试试看您可以使用正则表达式来匹配:
import re
s = 'Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))'
regx = r'(Conv2d).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*?(\d+).*'
print(re.sub(regx, r'\1(\2 -> \3, \4x\5, \6,\7,\8,\9)', s))
输出:
Conv2d(3 -> 64, 3x3, 1,1,1,1)
['TVLoss()', 'Conv2d(3 -> 64, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(64 -> 64, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(64 -> 128, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(128 -> 128, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(128 -> 256, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(256 -> 256, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'Conv2d(256 -> 256, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'Conv2d(256 -> 256, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(256 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(512 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'ContentLoss((crit): MSELoss())', 'Conv2d(512 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'Conv2d(512 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(512 -> 512, 3x3, 1,1, 1,1)', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())']
如果您想让regex稍微更加健壮,但代价是它相当长:
(Conv2d)\((\d+),\s(\d+),\skernel_size=\((\d+),\s(\d+)\),\sstride=\((\d+),\s(\d+)\),\spadding=\((\d+),\s(\d+)\)\)
试试看您可以使用regex解析字符串中函数的签名,将参数转换为所需语法,然后使用
re.sub
添加新签名:
import re
import itertools
def signature(header):
s = re.findall('(?<=\()[\w\W]+(?=\)$)', header)
return re.split(',\s(?=\w\w)', s[0]) if s else ''
def combine_args(d):
if '=' in d:
return '{}x{}'.format(*re.findall('\d+', d)) if 'kernel_size' in d and len(re.findall('\d+', d)) == 2 else '{},{}'.format(*re.findall('\d+', d)) if len(re.findall('\d+', d)) == 2 else d
return d
def combine_header(d):
vals = [[a, list(b)] for a, b in itertools.groupby(d, key=lambda x:x.isdigit())]
return list(itertools.chain(*[[' -> '.join(b)] if a else [combine_args(i) for i in b] for a, b in vals]))
lines = ['TVLoss()', 'Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'ContentLoss((crit): MSELoss())', 'Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())']
final_lines = [re.sub('(?<=\()[\w\W]+(?=\)$)', ', '.join(combine_header(c)), a) for a, c in zip(lines, map(signature, lines))]
您可以使用regex解析字符串中函数的签名,将参数转换为所需语法,然后使用
re.sub
添加新签名:
import re
import itertools
def signature(header):
s = re.findall('(?<=\()[\w\W]+(?=\)$)', header)
return re.split(',\s(?=\w\w)', s[0]) if s else ''
def combine_args(d):
if '=' in d:
return '{}x{}'.format(*re.findall('\d+', d)) if 'kernel_size' in d and len(re.findall('\d+', d)) == 2 else '{},{}'.format(*re.findall('\d+', d)) if len(re.findall('\d+', d)) == 2 else d
return d
def combine_header(d):
vals = [[a, list(b)] for a, b in itertools.groupby(d, key=lambda x:x.isdigit())]
return list(itertools.chain(*[[' -> '.join(b)] if a else [combine_args(i) for i in b] for a, b in vals]))
lines = ['TVLoss()', 'Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())', 'Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'ContentLoss((crit): MSELoss())', 'Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)', 'Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))', 'ReLU(inplace)', 'StyleLoss((gram): GramMatrix()(crit): MSELoss())']
final_lines = [re.sub('(?<=\()[\w\W]+(?=\)$)', ', '.join(combine_header(c)), a) for a, c in zip(lines, map(signature, lines))]
谢谢你的帮助!例如,我如何使用正则表达式将
Conv2d(3,64,kernel\u size=(3,3),stride=(1,1),padding=(1,1))
更改为64,3
?我试图将MaxPool2d(kernel\u size=2,stride=2,padding=0,dislation=1,ceil\u mode=False)
放入与上面的regx变量相同的设置中,但我无法让它工作。但是我想格式有点不同?您希望输出是什么样子的?我需要它看起来像:MaxPool2d(2x2,2,2)
。此外,根据用户的选择,“MaxPool”字符串将改为如下:AvgPool2d(kernel\u size=2,stride=2,padding=0)
。“AvgPool”字符串需要以与MaxPool相同的格式结束:AvgPool2d(2x2,2,2)
。我不确定这两个字符串是否足够相似,是否可以将它们合并成一个regx。也许最好的选择是定义一个regx变量,为所有3个字符串设置/格式创建一个映射,然后我可以添加MaxPool2d
,AvgPool2d
,或Conv2d
当我想要打印图层名称/字符串时。谢谢您的帮助!例如,我如何使用正则表达式将Conv2d(3,64,kernel\u size=(3,3),stride=(1,1),padding=(1,1))
更改为64,3
?我试图将MaxPool2d(kernel\u size=2,stride=2,padding=0,dislation=1,ceil\u mode=False)
放入与上面的regx变量相同的设置中,但我无法让它工作。但是我想格式有点不同?您希望输出是什么样子的?我需要它看起来像:MaxPool2d(2x2,2,2)
。此外,根据用户的选择,“MaxPool”字符串将改为如下:AvgPool2d(kernel\u size=2,stride=2,padding=0)
。“AvgPool”字符串需要以与MaxPool相同的格式结束:AvgPool2d(2x2,2,2)
。我不确定这两个字符串是否足够相似,是否可以将它们合并成一个regx。也许最好的选择是定义一个regx变量,为所有3个字符串设置/格式创建一个映射,然后我可以添加MaxPool2d
,AvgPool2d
,当我想打印图层名/字符串时,也可以使用Conv2d。