【问题标题】:Splitting up a text file into sets of n characters将文本文件拆分为 n 个字符的集合
【发布时间】:2013-04-25 18:18:14
【问题描述】:

所以我有一个带有一堆数字的长文本文件,我想重新格式化这个文件,以便每 12 个字符在自己的行上,文件长 4392 个字符。我的策略是将 infile 的内容添加到列表和切片中,并将前 12 个字符附加到新列表中,然后使用列表切片参数的 while 循环将其写入输出文件。我在out.writelines(l) 上遇到错误:

TypeError: writelines() argument must be a sequence of strings.

这是我的代码:

l = []
outl=[]
with open('r6.txt', 'r') as f, \
     open('out.txt', 'w') as out:
     outl.append(f)
     a = 0
     b = 11 
     while b <= 4392:
         l.append(outl[a:b])
         l.append('/n')
         out.writelines(l)
         a+=12
         b+=12
         l=[]

【问题讨论】:

    标签: python list format slice


    【解决方案1】:

    好吧,您将文件对象附加到列表中,然后您将获取列表的切片并写入它们。也许您忘记了字符串中的文件对象引用。

    只需使用print outl 即可获得答案。如果您在列表中的项目中有一个文件对象,那么您知道:)

    或者更好:

    l = []
    outl=[]
    with open('r6.txt', 'r') as f, \
         open('out.txt', 'w') as out:
         outl.extend(f.readlines())
         a = 0
         b = 11 
         while b <= 4392:
             l.append(outl[a:b])
             l.append('\n')
             out.writelines(l)
             a+=12
             b+=12
             l=[]
    

    【讨论】:

      【解决方案2】:

      嗯,虽然其他答案似乎是正确的,但我仍然认为最终的解决方案可以,嗯,更快:

      with open('r6.txt', 'r') as f, \
          open('out.txt', 'w') as out:
          # call anonymous lambda function returning f.read(12) until output is '', put output to part
          for part in iter(lambda: f.read(12), ''):
              # write this part and newline character
              out.write(part)
              out.write('\n')
      

      【讨论】:

      • 这是一个很好的方法,但是只有当输入文件是一个长行且其中没有换行符时,它才会正确格式化输出。 OP 没有说明原始文件的格式,但是您将如何处理他的输入文件中已经有多个换行符的情况?
      【解决方案3】:

      Vlad-ardelean 说您需要将f.readlines() 附加到outl 而不是文件f 是正确的。

      此外,您每次都使用writelines() 写入一行,但writelines() 旨在将字符串列表写入文件,而不是一个项目列表。插入换行符的更好方法可能是:

      l = []
      outl=[]
      with open('r6.txt', 'r') as f, \
          open('out.txt', 'w') as out:
          # gets entire file as one string and removes line breaks
          outl = ''.join(f.readlines()).replace('\n','')
          l = [outl[each:each+12]+'\n' for each in xrange(0,len(outl),12)]
          out.writelines(l)
      

      r6 的示例输入:

      abcdefeounv lernbtlttb
      berolinervio
      bnrtopimrtynprymnpobm,t
      2497839085gh
      b640h846j048nm5gh0m8-9
      2g395gm4-59m46bn
      2vb-9mb5-9046m-b946m-b946mb-96m-05n=570n;rlgbm'dfb
      

      输出:

      abcdefeounv 
      lernbtlttbbe
      rolinerviobn
      rtopimrtynpr
      ymnpobm,t249
      7839085ghb64
      0h846j048nm5
      gh0m8-92g395
      gm4-59m46bn2
      vb-9mb5-9046
      m-b946m-b946
      mb-96m-05n=5
      70n;rlgbm'df
      b
      

      【讨论】:

      • 非常感谢凯文,这是完美的。我喜欢你处理换行符的策略。你介意解释一下你的 for 循环吗?我从未见过它被这样使用。
      • for 循环是一个列表推导。您可以阅读它们,它们并不太复杂。但是outl[each:each+12]+'\n' 取原始行的 12 个字符切片并附加一个换行符,for each in xrange(0,len(outl),12) 表示它从 0 开始,按照字符串的长度,并以 12 为增量循环。列表理解部分 @ 987654331@ 表示循环的输出被分配给列表l
      猜你喜欢
      • 2017-01-07
      • 1970-01-01
      • 2023-03-02
      • 1970-01-01
      • 1970-01-01
      • 2011-03-12
      • 1970-01-01
      • 2021-06-29
      • 2021-09-19
      相关资源
      最近更新 更多