【问题标题】:How to transform a list into a CSV file with N items per row?如何将列表转换为每行 N 项的 CSV 文件?
【发布时间】:2017-05-11 06:17:30
【问题描述】:

我想创建一个新的 CSV 文件,每行包含 3 个项目。 我的源文件看起来像(没有新行/换行符):

12123, 1324, 232324, 243443, 234, 2345, 2334, 2445, 22355, 222234, 2345

现在我想将此文件转换为 CSV 文件。取前三个元素放在第一行,换行,取后面三个元素,等等……

12123, 1324, 232324
24343, 234, 2345
...

如何使用 Python 3.x 做到这一点?我是Python新手,不明白... 我之前的尝试:

import csv

with open('test.csv') as f:
    reader = csv.reader(f)
    with open('test2.csv', 'w') as csvfile:
        writer = csv.writer(csvfile)
        liste = list(reader)
        print(liste[1:2])

但我的列表对象只有一个长项。

【问题讨论】:

  • 这里有多个问题,一次解决一个:(1)如何读取CSV(2)如何取列表的前三个元素(3)如何编写CSV。尝试自己解决每个问题。您甚至不需要涉及与解决 (2) 相关的任何文件或任何 CSV。
  • liste 是一个列表列表:每个内部列表都是文件的一行。您需要遍历liste 并获取每个子列表的前三个对象。

标签: python list python-3.x csv


【解决方案1】:

你提到:

我的源文件看起来像(没有新行/换行符):

12123、1324、232324、243443、234、2345 2334、2445、22355、222234、2345

因此,这会读取 CSV 的一长行,然后将其写入为每行三个一组:

import csv

with open('test.csv',newline='') as f:
    reader = csv.reader(f)
    line = next(reader) # Read the one long line

with open('test2.csv', 'w', newline='') as csvfile:
    writer = csv.writer(csvfile)
    for i in range(0,len(line),3): # step by threes.
        writer.writerow(line[i:i+3])

请注意,正确使用 csv 模块需要在 Python 3 中使用 newline=''(Python 2 中的“rb”或“wb”)打开文件。

【讨论】:

    【解决方案2】:

    文件 I/O 中立解决方案:

    csv = """12123, 1324, 232324, 243443, 234, 2345
    
    2334, 2445, 22355, 222234, 2345"""  # replace this with the file you read from CSV
    
    def sixPerLineToThreePerLine(s):
      result = ""
      for line in s.split("\n"):
        sp = line.split(", ")
        result = result + ", ".join(sp[:3]) + "\n" + ", ".join(sp[3:])
      return result
    
    print(sixPerLineToThreePerLine(csv))  # replace this with code to write to CSV
    

    【讨论】:

      【解决方案3】:

      这是一个解决方案,但它有点长。基本上我会将 csv 中的所有值写入一个列表,然后从列表中删除三个值并写入 csv,直到没有剩余值为止。

      import csv
      
      # just an example csv
      with open('example.csv', 'w') as csvfile:
          # create example csv with a single row of numbers 0-19
          spamwriter = csv.writer(csvfile)
          spamwriter.writerow([i for i in range(20)])
      
      # open file for reading, append values to list
      l = []
      with open('example.csv') as csvfile:
          # read the example file into a list
          reader = csv.reader(csvfile)
          for row in reader:
              for val in row:
                  l.append(val)
      
      
      # write to the original file with 3 values per line
      with open('example.csv', 'w') as csvfile:
          spamwriter = csv.writer(csvfile)
          while l:
              try:
                  # write to file 3 values at a time
                  spamwriter.writerow(l[:3])
                  l = l[3:]
              except:
                  # add last bit of file, if file doesn't devide evenly by 3
                  spamwriter.writerow(l)
                  break
      

      我建议您查看Pandas 我发现用它来操作 csvs 要容易得多,但它不在标准库中。

      【讨论】:

        【解决方案4】:

        这应该会有所帮助。这是使用 python 2.7 编写的,所以如果您在 3.x 中运行它有任何问题,请告诉我,我可以尝试提供帮助。

        import csv # import the csv module you will need, if you want to avoid this you can just read it in as a text file
        output = """""" # make an output string
        num = 0 #initialize num that trakcs how many numbers have ben read
        with open('datacsv.csv', 'rb') as f: # open the input file
            file = csv.reader(f) # initialize the file as being a csv file
            for row in file: # for every row (you said no new lines, but just in case)
                for data in row: # for ever entry in the row
                    if(num == 2): # if you have read in three numbers
                        num = 0 # reset num
                        output += data + "\n" # output a new line and the current number
                    else:
                        num += 1 # increment num
                        output += data + "," # add to output the data and a comma
        
        
        new = open("outputcsv.csv", "w") # create the output file
        new.write(output) # write the output data to the new file
        

        【讨论】:

          【解决方案5】:

          我写了一个简短的程序,我认为它可以满足您的需求:

          它从读取器文件中读取所有行,然后将它们插入写入器文件 3 by 3 :)

          import csv
          
          def main():
          
              with open('ex.csv', 'rb') as f:
              reader = csv.reader(f)
              with open('ex2.csv', 'wb') as csvfile:
                  writer = csv.writer(csvfile)
                  pass_on = []
          
                  for row in reader:
                      #print row
          
                      for c in xrange(0, len(row)): # passing on objects after count of 3
                          if row[c]:
                              pass_on.append(row[c])
          
          
                  print pass_on
          
                  while pass_on:
          
                      writer.writerow(pass_on[:3])
                      pass_on = pass_on[3:]
          
          
          
              print "done"
          
          if __name__ == '__main__':
              main()
          

          【讨论】:

            【解决方案6】:

            您要做的是从文件中读取数据,然后将其拆分为单个元素。一旦你把它放在单独的元素中,你可以把它们分成三个一组并写入你的输出文件。

            这样的事情应该可以工作:

            def read_data(file_path):
                with open(file_path, 'r') as fh:
                    elements = fh.read()
                data = [element.strip() for element in elements.split(',')]
                return data
            
            def group(data):
                grouped = [', '.join(data[n:n+3]) for n in range(0, len(data), 3)]
                return grouped
            
            def write(data, output):
                with open(output, 'w') as fh:
                    fh.writelines(data)
            
            def main():
                data = read('test.csv')
                data = group(data)
                write(data, 'test2.csv')
            

            【讨论】:

            • 我认为在read_data() 中你应该改用open(file_path, 'r') as fh
            • 啊,是的。谢谢。
            【解决方案7】:

            没有csv 模块的四行解决方案:

            with open('oneline_numbers.csv') as fobj_in, open('three_numbers.csv', 'w') as fobj_out:
                numbers = iter(entry.strip() for entry in next((fobj_in)).split(','))
                for line in zip(*[numbers] * 3):
                    fobj_out.write(', '.join(line) + '\n')
            

            【讨论】:

              猜你喜欢
              • 2018-10-25
              • 1970-01-01
              • 2019-11-20
              • 1970-01-01
              • 1970-01-01
              • 2016-07-11
              • 2017-03-27
              • 2016-01-15
              • 2020-05-24
              相关资源
              最近更新 更多