使用python 2.x读入并格式化文本文件

时间:2015-02-17 09:00:25

标签: python

如果我的文本文件中的数据如下所示:

# 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“或其他......我将永远知道这是先验的。这样做的最佳做法是什么?

3 个答案:

答案 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))

这比其他两种方法更能控制逻辑。