如果我的文本文件中的数据如下所示:
# this is a header
# and so is this
#
alligator 27.2 83.4
bear 23.9 90.2
cat 12.56 0.98
dog 15.97 0.88884
...
...
...我知道我可以使用以下代码块读取该数据(列出与数据行对应的列表):
file1 = 'tmp.txt'
file1_data = []
data_input = open(file1,'r')
for line in data_input:
if "#" not in line:
line = line.strip().split()
first_col_datum = line[0]
second_col_datum = float(line[1])
third_col_datum = float(line[2])
file1_data.append([first_col_datum,second_col_datum,third_col_datum])
data_input.close()
...但我的直觉告诉我,有一种更优雅的方式来完成这项任务。基本上我想逐行读取文件,忽略'#',并为该行中的每个元素提供一个'format'命令(如[“%s”,“%0.6f”,“% 0.6f“,”%0.6f“,”%i“或其他......我将永远知道这是先验的。这样做的最佳做法是什么?
答案 0 :(得分:2)
如果要在文件中间写入
fileinput module
。
import fileinput
for line in fileinput.input("C:\\Users\\Administrator\\Desktop\\new.txt",inplace=True):
if not re.match(r"^#.*$",line):
#do the formatting
print "something", #print("something", end ="") for python 3
完成几行
记住你在文件中打印的内容。所以你必须阅读并打印每一行并修改你想要替换的任何一行。另外使用print "asd",
最后的,
是重要的它会阻止print
在那里添加换行符。
现在你不看lines starting with
#`。
添加条件。
if not re.match(r"^#.*$",line):
#do the formatting and print
答案 1 :(得分:1)
file1_data = []
with open(file1) as data_input: # with automatically closes your files
# skip headers
next(data_input), next(data_input), next(data_input)
for line in data_input:
# unpack
first_col_datum, second_col_datum, third_col_datum = line.split()
file1_data.append([first_col_datum,float(second_col_datum), float(third_col_datum)])
输出:
[['alligator', 27.2, 83.4], ['bear', 23.9, 90.2], ['cat', 12.56, 0.98], ['dog', 15.97, 0.88884]]
或使用itertools.islice跳过标题:
from itertools import islice
with open(file1) as data_input:
for line in islice(data_input,3,None):
first_col_datum, second_col_datum, third_col_datum = line.split()
file1_data.append([first_col_datum,float(second_col_datum),float(third_col_datum)])
print(file1_data)
[['alligator', 27.2, 83.4], ['bear', 23.9, 90.2], ['cat', 12.56, 0.98], ['dog', 15.97, 0.88884]]
我不确定我是否完全理解格式化部分或您想要用它做什么,但如果您想格式化使用str.format:
([first_col_datum, "{:6f}".format(float(second_col_datum)),"{:6f}".format(float(third_col_datum))])
如果您尝试使用if语句忽略以#
开头的行,则应使用str.startswith
:
if not line.startswith("#")
不确定您的问题在哪里表示您要将数据写入文件,但如果您这样做:
from itertools import islice
with open(file1) as data_input, open("output.txt","w") as out:
for line in islice(data_input,3,None):
first_col_datum, second_col_datum, third_col_datum = line.split()
out.write("{} {:6f} {:6f}\n".format(first_col_datum,float(second_col_datum), float(third_col_datum)))
答案 2 :(得分:1)
我们可以通过列表理解中的lambda或带有map函数的lambda来实现此目的的最简单方法
desired_list = lambda str_list: [str_list[0], float(str_list[1]), float(str_list[2])]
# With list comprehension
with open(file1) as fo:
output_list = [desired_list(content.strip().split(" ", 3) for content in fo.read().split("\n") if content and '#' not in content]
# With filter and map function
output_list = []
with open(file1) as fo:
fitered_list = filter(lambda x: if x and '#' not in x, fo.read().split("\n"))
output_list = map(desired_list, filtered_list)
我更喜欢将逻辑放入一个函数并调用它而不是使用lambda,就像Padraic Cunningham一样。
def desired_list(line):
if not line.strip() and '#' in line.strip():
return None
line_list = line.split(" ", 3)
return [line_list[0], float(line_list[1]), float(line_list[2])]
with open(file1) as fo:
file_contents = fo.read().split("\n")
output_list = filter(None, map(desired_list, file_contents))
这比其他两种方法更能控制逻辑。