enumerate(fileinput.input(file)) 和 enumerate(file) 之间的区别

6
我需要帮助我的代码,以下是代码内容:

for file in file_name :
    if os.path.isfile(file):
        for line_number, line in enumerate(fileinput.input(file, inplace=1)):
            print file
            os.system("pause")
            if line_number ==1:
                line = line.replace('Object','#Object')
                sys.stdout.write(line)

我想修改一些之前提取的文件,以便使用matplotlib绘制它们。为此,我删除了一些行,并注释了其他一些行。
我的问题是:
- 使用for line_number, line in enumerate(fileinput.input(file, inplace=1)):仅给我提供了5个文件中的4个(当查看file_name列表包含5个引用时!) - 使用for line_number, line in enumerate(file):给我提供了之前提取的5个文件,但我不知道如何在不创建另一个文件的情况下对其进行修改...
你有关于这个问题的想法吗?这是一个正常的问题吗?

不知道为什么它没有出现,但开头缺少一个“大家好”.. 尝试编辑它,但似乎它没有出现。 - flor14n
Stack Overflow会自动删除问候语,因为它们与问题无关。 - Adam Smith
请你在代码开头定义“file_name”变量。 - PythonTester
抱歉,另外请确认您正在使用Python 2.5+,或者确切地说您正在使用哪个版本的Python。 - PythonTester
file_name 是一个包含 file_1、file_2、file_3 等文件的列表。 - flor14n
2个回答

2

有一些事情可能会对您有所帮助。

首先,file_name 看起来是一个文件名列表。更好的命名方式可能是 file_names,然后您可以为每个文件使用 file_name。您已经验证了它包含 5 个条目。

enumerate() 函数用于在枚举项目列表时提供索引和每个循环项。这样可以避免使用单独的计数器变量,例如:

for index, item in enumerate(["item1", "item2", "item3"]):
    print index, item

将输出:

0  item1
1  item2
2  item3

实际上这并不是必需的,因为您选择使用fileinput库。该库旨在接受文件列表,并在一个循环中遍历所有文件中的所有行。因此,您需要稍微调整一下方法,假设您的文件列表名为file_names,则可以编写以下内容:

# Keep only files in the file list
file_names = [file_name for file_name in file_names if os.path.isfile(file_name)]

# Iterate all lines in all files
for line in fileinput.input(file_names, inplace=1):
    if fileinput.filelineno() == 1:
        line = line.replace('Object','#Object')
        sys.stdout.write(line)  

这里的主要观点是,在将列表传递给fileinput之前,最好预先过滤掉任何非文件名。我会让您自行修复输出。

fileinput提供了许多函数来帮助您确定当前正在处理哪个文件或行号。


谢谢回复,我会看一下这个! - flor14n

0

假设您仍然遇到问题,我的典型方法是只读方式打开文件,将其内容读入变量中,关闭文件,创建一个 edited 变量,以写模式打开文件(覆盖原始文件),最后写入 edited 的内容。

我喜欢这种方法,因为如果我想要在不删除原始文件的情况下测试编辑,我只需更改要写出的文件名即可。

此外,我建议使用复数名词命名容器,就像@Martin Evans建议的那样。

import os

file_names = ['file_1.txt', 'file_2.txt', 'file_3.txt', 'file_4.txt', 'file_5.txt']
file_names = [x for x in file_names if os.path.isfile(x)] # see @Martin's answer again

for file_name in file_names:
    # Open read-only and put contents into a list of line strings
    with open(file_name, 'r') as f_in:
        lines = f_in.read().splitlines()

    # Put the lines you want to write out in out_lines
    out_lines = []
    for index_no, line in enumerate(lines):
        if index_no == 1:
            out_lines.append(line.replace('Object', '#Object'))
        elif ...
        else:
            out_lines.append(line)

    # Uncomment to write to different file name for edits testing
    # with open(file_name + '.out', 'w') as f_out:
    #     f_out.write('\n'.join(out_lines))

    # Write out the file, clobbering the original
    with open(file_name, 'w') as f_out:
        f_out.write('\n'.join(out_lines))

这种方法的缺点是每个文件都必须足够小,以适应内存两次 (lines + out_lines)。

祝你好运!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接