简体   繁体   English

如何将一行从.txt文件复制到经过修改的新.txt文件中

[英]How to copy a line from a .txt file into a new .txt file with modifications

I'm trying to copy lines in a .txt file and write them into a new .txt file with minor changes. 我正在尝试将.txt文件中的行复制并通过较小的更改将它们写入新的.txt文件中。 For example, if the file reads 0 is less than 1 , I want to copy that into a new one but say ZERO is less than ONE . 例如,如果文件读取0 is less than 1 ,我想将其复制到一个新文件中,但说ZERO is less than ONE I've been able to create a new file but nothing gets written into it. 我已经能够创建一个新文件,但是没有写入任何文件。

def numbers(fileName):
file = open(fileName, "r")
newFile = 'converted.txt'
converted = open(newFile, "w")
for line in file:
    if "0" in line:
        line.replace("0", "ZERO")
    elif "1" in line:
        line.replace("1", "ONE")
    else:
        return
return

There are two big problems with your code: 您的代码有两个大问题:

First, line.replace won't do anything to line itself. 首先, line.replace不会做任何line本身。 As the docs say, it will: 正如文档所说,它将:

Return a copy of the string with all occurrences of substring old replaced by new… 返回该字符串的副本,其中所有出现的子字符串old都被new替换。

But you're not storing that new string, or doing anything else with it. 但是您不会存储该新字符串,也不会对其进行任何其他操作。

Second, you never write anything to converted . 其次,您从不写任何要converted

To fix both at once: 一次修复两个问题:

for line in file:
    if '0' in line:
        converted.write(line.replace('0', 'ZERO'))
    elif '1' in line:
        converted.write(line.replace('1', 'ZERO'))
    else:
        return

However, you also have a number of small problems. 但是,您还有许多小问题。 You return the first time you find a line with no 0 s or 1 s. 第一次找到没有0 s或1 s的行时return If a line has both 0 s and 1 s, you will only replace the 0 s. 如果一行同时包含0 s和1 s,则仅替换0 s。 You never close the file, which means the file may never get flushed to disk, and could end up empty or incomplete. 您永远不会close文件,这意味着文件可能永远不会刷新到磁盘,并且最终可能为空或不完整。 So, let's fix all of those problems as well: 因此,我们也修复所有这些问题:

with open(fileName, "r") as file, open('converted.txt', 'w') as converted:
    for line in file:
        line = line.replace("0", "ZERO")
        line = line.replace("1", "ONE")
        converted.write(line)

It's perfectly safe to replace all the 0s even if there aren't any—it just won't do anything. 即使不存在任何一个,也非常安全地replace所有0,因为它什么也不会做。 (If you were trying to optimize things by skipping the expensive work if there was no work to do, the "0" in line takes just as long as the replace when there's nothing to do, so you've actually pessimized things… which is a good lesson to learn early in your programming career.) This means you don't need the if statements at all, you don't have to fix the way you've chained them up, and you don't have the problem with the return in the else . (如果您试图通过在没有工作要做的情况下跳过昂贵的工作来优化事物,那么在无事可做的情况下, "0" in linereplace条目所花费的时间一样长,因此您实际上对事物感到悲观……这是这是一个很好的课程,可以在您的编程生涯中早期学习。)这意味着您根本不需要if语句,也不必修复将它们链接起来的方式,并且也没有问题在returnelse

And the with statement automatically calls close on both file and converted for you as soon as you leave it (even if you leave early because of, say, an unexpected exception). 并且with语句会自动在两个file上调用close ,并在您离开file立即为您converted (即使您由于意外的异常而提前离开)。

  1. Use with when opening files to automatically clean them up. 使用with打开文件时自动清除它们。
  2. You never actually write anything to the file 您实际上从未向文件写入任何内容
  3. Are you sure you want to return if the line doesn't have a 0 or 1 ? 如果该行没有01您确定要return吗?

- -

def numbers(filename):
    with open(filename, 'rU') as file_in:
        with open('converted.txt', 'w') as file_out:
            for line in file_in:
                if '0' in line:
                    line = line.replace('0', 'ZERO')
                elif '1' in line:
                    line = line.replace('1', 'ONE')

                file_out.write(line)

Both TkTech and abarnet have some good advice in terms of how to open the file and save the return values. TkTech和abarnet都在如何打开文件和保存返回值方面提供了一些好的建议。 Automatic clean up is nice. 自动清理很好。

There is a logical issue afoot though. 仍然有一个逻辑问题。 In the example sentence you gave, "0 is less than 1" that single line has both a "0" and a "1" in it. 在您给的示例句子中,“ 0小于1”表示单行中同时包含“ 0”和“ 1”。 If you were to send that line through either function, it would modify the line to be "ZERO is less than 1" not your intended "ZERO is less than ONE." 如果要通过任一功能发送该行,则会将该行修改为“零小于1”,而不是预期的“零小于一”。 The reason for this is because the first if statement would catch the "0" but the use of elif or even else would indicate to the program "you already found the first condition, don't bother checking the rest." 这样做的原因是因为第一个if语句将捕获“ 0”,但是使用elif或其他方式将向程序指示“您已经找到了第一个条件,不必费心检查其余条件”。 Since you want to catch any 1's regardless of whether or not any 0's exist, you shouldn't use any sort of else statement. 由于要捕获任何1而不管是否存在0,因此不应使用任何其他else语句。

Here is how I would write it: 这是我的写法:

def convert(file):
    in_file = open(file, "r")
    out_file = open("/home/user/temp/converted.txt", "w+")
    # Read up on what r and w+ mean; docs.python.org

    for line in in_file:
        # Catch 0 in line
        if "0" in line:
            line = line.replace("0", "ZERO")

        # Catch 1 in line
        if "1" in line:
            line = line.replace("1", "ONE")

        # Write line to file
        out_file.write(line)
    #end for

    # Close open files; this is common practice in C
    # Not needed in Python when using "with open(file, 'r') as filename:"
    in_file.close()

    # Force it to write out anything left in buffer; not usually needed as Python usually does this when calling close()
    out_file.flush()
    out_file.close()

There are a number of improvements that could be made to my code, in addition to improvements that could be made depending on the format of the intended input file. 除了可以根据预期输入文件的格式进行的改进之外,还可以对我的代码进行许多改进。

  1. I could use TkTech's suggestion and then I wouldn't need to close anything at the end. 我可以使用TkTech的建议,然后最后不需要关闭任何内容。
  2. If I wanted to look for more than just a couple things I could use a dictionary or other data structure to store all the intended changes. 如果我想寻找的不仅仅是几件事,我可以使用字典或其他数据结构来存储所有预期的更改。

It does, however work in it's current state taking this: 它确实可以,但是在当前状态下可以这样做:

0 is less than 1
1 is greater than 0
0 1
1     0

and giving me this: 并给我这个:

ZERO is less than ONE
ONE is greater than ZERO
ZERO ONE
ONE     ZERO

A file more complex than this may give you unintended results, such as: 比此文件更复杂的文件可能会给您带来意想不到的结果,例如:

0 is less than 1 but larger than -1 ==> ZERO is less than ONE but larger than -ONE
0 is larger than -1 ==> ZERO is larger than -ONE
2 is larger than 0 ==> 2 is larger than ZERO
0 1 2 3 4 5 6 7 8 9 10 ==> ZERO ONE 2 3 4 5 6 7 8 9 ZEROONE
0000001 ==> ZEROZEROZEROZEROZEROZEROONE
1001101 ==> ONEZEROZEROONEONEZEROONE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM