基于this answer,我使用changethis方法
import numpy as np
import os
def changethis(pos):
appex = sfile[pos[1]-1][:pos[2]] + '*' + file[pos[1]-1][pos[2]+len(pos[0]):]
file[pos[1]-1] = appex
pos = ('stack', 3, 16)
sfile = np.genfromtxt('in.cpp',dtype='str',delimiter=os.linesep)
changethis(pos)
print(file)其中,in.cpp是一个源文件,其中包含以下内容:
/* Multi-line
comment
*/
#include <iostream>
#include <fstream>
using namespace std;
int main (int argc, char *argv[]) {
int linecount = 0;
double array[1000], sum=0, median=0, add=0;
string filename;
if (argc <= 1)
{
cout << "Error" << endl;
return 0;
}我得到了输出:
['using namespace std;' 'int main (int argc, char *argv[]) {'
'int linecount = *' 'double array[1000], sum=0, median=0, add=0;'
'string filename;' 'if (argc <= 1)' '{' 'cout << "Error" << endl;'
'return 0;' '}']注意,多行注释、include语句和空行的行在ndarray中缺失。
我不明白为什么会发生这种情况,因为delimiter被设置为考虑每个行字符的变化。
关于产出如何的任何建议:
['/* Multi-line' 'comment' '*/' '' '#include <iostream>',
'' '#include <fstream>' '' 'using namespace std;'
'' 'int main (int argc, char *argv[]) {'
'int linecount = *' 'double array[1000], sum=0, median=0, add=0;'
'string filename;' 'if (argc <= 1)' '{' 'cout << "Error" << endl;'
'return 0;' '}']发布于 2016-04-29 08:44:55
再次为genfromtxt的使用感到抱歉,没有理解您的意图,只是试图为问题提供一个可能的解决方案。作为对该特定解决方案的后续行动(其他解决方案已经提供),您可以这样做:
import numpy as np
import os
def changethis(pos):
# Notice file is in global scope
appex = file[pos[1]-1][:pos[2]] + '*' + file[pos[1]-1][pos[2]+len(pos[0]):]
file[pos[1]-1] = appex
pos = ('stack', 3, 16)
file = np.array([i for i in open('in.txt','r')]) # instead of genfromtext.
changethis(pos)
print(file),结果是:
['/* Multi-line \n' 'comment\n' '*/\n*' '\n' '#include <iostream>\n'
'#include <fstream>\n' '\n' 'using namespace std;\n' '\n'
'int main (int argc, char *argv[]) {\n' ' int linecount = 0;\n'
' double array[1000], sum=0, median=0, add=0;\n' ' string filename;\n'
' if (argc <= 1)\n' ' {\n' ' cout << "Error" << endl;\n'
' return 0;\n' ' }']编辑:也是另一个用户提到的另一个相关问题,就是我为文件使用的范围。我并不是要告诉您在全局范围内做一些事情,我想解释的是,这个函数是工作的,因为文件在全局范围内。在任何情况下,您都可以创建一个函数来保存范围:
import numpy as np
import os
def changeallthese(poslist,path):
def changethis(pos):
appex = file[pos[1]-1][:pos[2]-1] + '*' + file[pos[1]-1][pos[2]-1+len(pos[0]):]
file[pos[1]-1] = appex
file = np.array([str(i) for i in open(path,'r')])
for i in poslist:
changethis(i)
return file
poslist = [('stack', 3, 16),('stack', 18, 1),('/* Multi-line', 1, 1)]
file = changeallthese(poslist,'in.txt')
print(file),其结果是:
['* \n' 'comment\n' '*/\n*' '\n' '#include <iostream>\n'
'#include <fstream>\n' '\n' 'using namespace std;\n' '\n'
'int main (int argc, char *argv[]) {\n' ' int linecount = 0;\n'
' double array[1000], sum=0, median=0, add=0;\n' ' string filename;\n'
' if (argc <= 1)\n' ' {\n' ' cout << "Error" << endl;\n'
' return 0;\n' '* }']要将数组写入文件,可以使用Python中的普通文件写入系统:
fid = open('out.txt','w')
fid.writelines(file)
fid.close(),或者使用numpy中的函数(但我不确定它是否会添加更多的尾行,请小心):
np.savetxt('out.txt',file,fmt='%s')发布于 2016-04-28 20:31:55
如果文件不太大:
import numpy as np
import os
def changethis(linelist,pos):
appex = linelist[pos[2]-1][:pos[3]] + pos[1] + linelist[pos[2]-1][pos[3]+len(pos[0]):]
linelist[pos[2]-1] = appex
pos = ('Multi','Three', 1, 3)
with open('in.cpp','r') as f:
lines=f.readlines()
changethis(lines,pos)
print(''.join(lines))readlines会把你的文件变成一个行列表(内存效率低,速度慢,但是可以完成这项工作)。如果小于1k行,就可以了)。
除了pos之外,该函数还接受行列表作为输入。我还修改了函数,使其使用pos[0]复制pos[1],而不是在pos[2]行和字符pos[3]之后使用*。
我得到这个作为输出:
/* Three-line
comment
*/
#include <iostream>
#include <fstream>
using namespace std;
int main (int argc, char *argv[]) {
int linecount = 0;
double array[1000], sum=0, median=0, add=0;
string filename;
if (argc <= 1)
{
cout << "Error" << endl;
return 0;
}发布于 2016-04-28 20:32:44
如果您想要表示文件行的字符串列表,请打开该文件并使用readlines()
with open('in.cpp') as f:
lines = f.readlines()
# Have changethis take the list of lines as an argument
changethis(lines, pos)不要使用np.genfromtxt;这是一个表格数据解析器,它具有各种不想要的行为,例如将#作为一个行注释标记。
根据您打算如何处理这个列表,您甚至可以避免需要一个明确的行列表。而且,file是变量名的糟糕选择(它隐藏了内置的file),changethis实际上应该将列表作为参数而不是全局变量。一般来说,你之前得到的答案是相当糟糕的。
https://stackoverflow.com/questions/36924519
复制相似问题