相对较新的python,试图找出解决此问题的最通用和可读的方法。执行速度也不会差,但它是次要问题。
我有另一个程序的输入文件,我需要自动编辑。格式类似于以下内容:
---Thousands of lines that can be ignored---
&Brand: Ford
&Define Class
&Model: Sedan
&Parameter: Cost
&Dollars
&25000
&Parameter: Stock
&Quantity
&14
&Brand: Honda
&Define Class
&Model: Sedan
&Parameter: Cost
&Dollars
&22000
&Parameter: Stock
&Quantity
&17
&Model: SUV
&Parameter: Cost
&Dollars
&35000
&Parameter: Stock
&Quantity
&7
---Thousands of lines that can be ignored---
我的代码需要自动更改数值参数。我遇到的麻烦是,我不只是匹配单个条件并改变一条线,我匹配非独特线的独特组合(参数:成本出现三次,两次出现在Model:Sedan下,两次出现在Brand下:本田,但在这两种条件下只有一次)。
正确我将新参数存储在嵌套字典中,例如:
params = {'Ford': {'Sedan': {'Cost': 17000, 'Stock': 43}}, 'Honda':{'Sedan': {'Cost': 19000, 'Stock': 12}, {'Truck': {'Cost': 33000, 'Stock': 5}}}
通过这种方式,我可以for brand in params.keys()
然后for model in params[brand].keys()
等等。
我有打开,关闭和修改文件的基础知识,它正在识别要修改的正确行,我遇到了麻烦。谢谢你的帮助。
例: 对于上面的示例字典,理想的输出是:
---Thousands of lines that can be ignored---
&Brand: Ford
&Define Class
&Model: Sedan
&Parameter: Cost
&Dollars
&17000
&Parameter: Stock
&Quantity
&43
&Brand: Honda
&Define Class
&Model: Sedan
&Parameter: Cost
&Dollars
&19000
&Parameter: Stock
&Quantity
&12
&Model: SUV
&Parameter: Cost
&Dollars
&33000
&Parameter: Stock
&Quantity
&5
---Thousands of lines that can be ignored---
答案 0 :(得分:1)
必须查看Python的正则表达式?看看''包。您可以使用它来搜索数字条目。你可以像这样识别感兴趣的行(从我的头顶而不是检查):
import re
...
m = re.match(r'&(\d+)', the_line)
if m:
print 'found ', m.group(1)
# modify it...
表达式匹配任意数量的数字(\ d +部分)。不确定是否&很特别,但如果是,你可以放在方括号内。
当然,您需要类似的正则表达式来捕获之前的行是成本,然后捕获该值。你可以用一个简单的标志来做到这一点,信号网络是成本。
答案 1 :(得分:1)
您可以阅读第while
行\n\n
:
import re
model=''
brand=''
whit open('old_file') as f1,open('out_file','w') as f2:
for line in f1:
while line !='\n\n':
if 'Brand' in line :
brand=re.match(r'&Brand:(.*)',line).group(1)
f2.write(line)
elif 'Model' in line:
model=re.match(r'&Model:(.*)',line).group(1)
f2.write(line)
elif model and brand:
if line.strip('&')=='Dollars':
f2.write('Dollars'+'\n'+params[brand.strip()][model.strip()]['Cost'])
elif line.strip('&')=='Quantity':
f2.write('Dollars'+'\n'+params[brand.strip()][model.strip()]['Stock'])
else:
f2.write(line)
答案 2 :(得分:1)
这样的事可能有用。我创建了一个生成器,然后您可以迭代以编写更新的文件。
def get_lines(dic):
brand = ''
model = ''
parameter = ''
with open('testinput.txt', 'r') as fil:
for line in fil:
if line[1:].strip().isdigit() and brand in dic and model in dic[brand] and parameter in dic[brand][model]:
yield '&{0}\n'.format(dic[brand][model][parameter])
elif line.startswith('&Brand:'):
brand = line.split(': ')[-1].strip()
yield line
elif line.startswith('&Model:'):
model= line.split(': ')[-1].strip()
yield line
elif line.startswith('&Parameter:'):
parameter= line.split(': ')[-1].strip()
yield line
else:
yield line
params = {'Ford': {'Sedan': {'Cost': 17000, 'Stock': 43}}, 'Honda':{'Sedan': {'Cost': 19000, 'Stock': 12}, 'Truck': {'Cost': 33000, 'Stock': 5}}}
with open('output.txt', 'w') as fil:
for line in get_lines(params):
fil.write(line)
答案 3 :(得分:0)
import re,fileinput
def print_new_data(brand,model,data):
print "&Brand: %s"%(brand)
print "&Define Class"
print "&Model: %s"%(model)
print "&Parameter: Cost"
print "&Dollars"
print "&%s"%data["cost"]
print "&Parameter: Stock"
print "&Quantity"
print "&%s\n"%data["stock"]
def process(fh):
line = next(fh)
brand= re.findall("Brand: (.*)",line)
if not brand or brand[0] not in my_list_of_brands::
print line
return
brand = brand[0]
junk = next(fh)
model_line = next(fh)
model_name = re.findall("Model: (.*)",model_line)[0]
if model_name not in my_data[brand]:
print line
print junk
print model_line
return
while line.strip():
next(fh)
print_new_data(brand,model,my_data[brand][model])
fh = fileinput.open(["my_data_file"],inplace=1):
while True:
process(fh)