【问题标题】:How to edit a text file?如何编辑文本文件?
【发布时间】:2019-01-30 21:16:17
【问题描述】:

我正在尝试在 python 3.7 中编辑文本文件。基本上,我有一个包含数字的文本文件 (file_1.txt) - 3 列和 5 行,就像这样

1, 10, 20
2, 20, 30
3, 30, 50
4, 35, 60
5, 50, 100

我想编辑那个文件以获得一些不同的东西,基本上就是这个

1, 10, 20
2, 20, 30
3, 30, 50
4, 35, 60
5, 50, 100
6, 10, 20
7, 20, 30
8, 30, 50
9, 35, 60
10, 50, 100

复制第二列和第三列,第一列继续数字,每新行添加一个。 我试图做到这一点,但我没有成功。这是我尝试过的:

with open("file_1.txt", "r+") as file1:
    file1.read()
    i = 6
    imax = 10
    while i <= imax:
        sentence = str(i) + "\n"
        file1.write(sentence)
        i = i + 1

我不明白如何复制第二列和第三列。

有人知道怎么做吗?

【问题讨论】:

  • 看起来您只是将数据附加到文件中。这是您想知道的,还是“编辑”会涉及其他事情,例如更改现有行或删除其中一些。
  • 您需要拆分行以获取列。 line.split(',') 将生成一个具有 3 个索引的向量... 使用 3 列写入:file1,write(firstcolumn + ', ' + secondcolumn + ', ' +thirdcolumn)
  • 我试图拆分行,但后来我得到了字符串,我不知道如何用它制作第一列,将这些值添加到新列表中也存在问题
  • 我不在乎我是否有一个包含这 10 行和 3 列的新文件(例如 file_2.txt),或者我在现有文件中附加了另外 5 行。
  • @CroSimpson2.0 请看下面我的回答。

标签: python file text python-3.7


【解决方案1】:

如果这是一个类似 csv 的文件,您可能需要使用 pandas(这是处理数据框的最佳方法之一)。一个简单的例子:

import pandas as pd
df = pd.read_csv("<path_to_data_file>", header=None)
df = pd.concat([df, df])
df[0] = list(range(1, 11))
df.to_csv("result.csv", header=None, index=None)

【讨论】:

  • 感谢您的建议。如果你知道没有这个模块的任何其他方式,我很想看看。
  • @CroSimpson2.0 下面有几个没有熊猫的工作解决方案。但是,pandas 是用于数据管道的最强大(和标准)库之一(以及 numpy、scipy 等),您绝对应该尝试使用它,因为它使用起来更简单。
【解决方案2】:

下面的脚本将构建新文件,您可以设置要创建的行数。

首先从输入文件中读取所有行,然后将您设置的行数写入新文件。

list_emitter 可以从给定列表中无限生成项目,因此您只需调整 output_lines_count 变量以使输出文件更大。

def list_emitter(l):
    """This generator will endlessly yield items from given list."""
    while True:
        for item in l:
            yield item


with open('file_1.txt') as input_file:
    lines = input_file.readlines()    # Create list of lines

with open('output_file.txt', 'w') as output_file:
    output_lines_count = 10 # Set how many output lines you want
    for counter, line in enumerate(list_emitter(lines)):
        if counter == output_lines_count:
            break
        first, second, third = line.strip().split() # Parse line
        output_file.write('{}, {} {}\n'.format(counter+1, second, third))

【讨论】:

    【解决方案3】:

    Pythonic 方式:它将换行符附加到文件中。

    with open('sample.txt', 'r') as f:
    l = [i.strip() for i in f.readlines()]
    max_row = int(l[-1].split(',')[0])
    
    x = [str(i) for i in range(max_row+1,11)]
    y = [i.split(',', 1)[-1] for i in l]
    
    with open('sample.txt', 'a') as f:
        for item in [x[i]+',' + y[i] for i in range(len(x))]:
            f.write("%s\n" % item)
    

    PS: max row 可以是行数的长度

    【讨论】:

      【解决方案4】:

      另一种方式:

      with open("test.txt", "r+") as file1:
          lines = file1.readlines()
          index = 0
          i = 6
          imax = 10
          while i <= imax:
              sentence = lines[index].split(", ")[1:]
              sentence.insert(0, str(i))
              file1.write(", ".join(sentence))
              i += 1
              index += 1
      

      输出:

      1, 10, 20
      2, 20, 30
      3, 30, 50
      4, 35, 60
      5, 50, 100
      6, 10, 20
      7, 20, 30
      8, 30, 50
      9, 35, 60
      10, 50, 100
      

      【讨论】:

        【解决方案5】:

        首先,您需要从输入中读取所有数据,并将其存储。

        然后再过一遍,写入文件。

        data = []
        
        with open("file_1.txt", "r+") as file1:
        
            # read the data
        
            for line in file1:
                # .strip() to remove the newline
                # .split(", ") to split into 3 values
                # map(int, ...) to convert each from string to integer
                index, column2, column3 = map(int, line.strip().split(", "))
        
                #save the second and third coluumn
                data.append((column2, column3))
        
            # now write it back again:
        
            for column2, column3 in data:
                index += 1  # continue incrementing the index
        
                # format the lines and write them into the file
                file1.write("{}, {}, {}\n".format(index, column2, column3))
        

        【讨论】:

          【解决方案6】:

          这个模块也可以:

          def edit(nrows, filename):
              nrows +=1 #to avoid off-by-one error because dealing with lists
          
              outf = open(filename, 'a')
          
              column_1 = [1, 2, 3, 4, 5]
              column_2 = [10, 20, 30, 35, 50]
              column_3 = [20, 30, 50, 60, 100]
          
              last_column_1 = column_1[-1]
              list_1 = list(range(last_column_1+1, last_column_1+nrows))
              list_2 = nrows//len(column_2)*column_2 + column_2[0:nrows%len(column_2)]
              list_3 = nrows//len(column_3)*column_3 + column_3[0:nrows%len(column_3)]
          
              for c1, c2, c3 in zip(list_1, list_2, list_3):
                  outf.write("{}, {}, {}\n".format(c1, c2, c3))
          
          if __name__ == '__main__':
              edit(10, 'file.txt')
          

          假设有一个带有文本的file.txt

          1, 10, 20
          2, 20, 30
          3, 30, 50
          4, 35, 60
          5, 50, 100
          

          【讨论】:

            【解决方案7】:

            简短易懂。只需 3 行。

            with open('file_1.txt', 'r+') as f:
                for num, content in enumerate(f.readlines()):
                    f.write(f'{num+6}, {content[3:]}')
            

            【讨论】:

              【解决方案8】:

              这种方法直接将每一行作为一个字符串处理,不需要拆分任何更多的列。

              第一个 for 循环将 Cols 2&3(带有前导逗号)提取到一个列表中,跟踪行数。第二个循环附加此列表以计数开始的递增索引。

              with open("file_1.txt", "r+") as file1:
                  our_data = []
                  count = 0
                  for line in file1:
                      first_comma_pos = line.find(',')
                      # extract cols 2&3 including the leading comma
                      our_data.append(line[first_comma_pos:])
                      count += 1
              
                  for i in range(count):
                      sentence = str(i + count) + our_data[i] + '\n'
                      file1.write(sentence)
              

              【讨论】:

              • 嗨,亚历克斯!我正在阅读您的代码,但我无法完全理解它。你能告诉我你为什么在你使用 find 方法的那一行写冒号吗?
              • @CroSimpson2.0 对不透明的代码感到抱歉,希望这个新编辑会更好一些。 str[a:] 将返回一个从第一个字符开始直到字符串结尾的子字符串(例如:'hello'[3:] # returns 'lo'),所以我使用它通过找到第一个逗号位置来提取 Cols 2 和 3
              猜你喜欢
              • 2023-03-26
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-04-21
              • 2017-07-10
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多