简体   繁体   English

如何将列表转换为每行 N 项的 CSV 文件?

[英]How to transform a list into a CSV file with N items per row?

I want to create a new CSV file with 3 items per row.我想创建一个每行 3 个项目的新 CSV 文件。 My source file looks like (there are no new lines / line breaks):我的源文件看起来像(没有新行/换行符):

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

Now I want to transform this file in a CSV file.现在我想将此文件转换为 CSV 文件。 Take the first three elements and put it in the first row, new line, and take the next three items, etc...取前三个元素放在第一行,换行,取下三个元素,依此类推...

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

How can I do that with Python 3.x?我怎样才能用 Python 3.x 做到这一点? I'm new in Python and don't get it... My previous attempt:我是 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])

But my list object has only one long item.但是我的列表对象只有一个很长的项目。

You mentioned:你提到:

My source file looks like (there are no new lines / line breaks):我的源文件看起来像(没有新行/换行符):

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

So this reads one long row of a CSV, then writes it as groups of three per line:因此,这会读取 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])

Note that correct use of the csv module requires the files to be opened with newline='' in Python 3 ('rb' or 'wb' in Python 2).请注意,正确使用csv模块需要在 Python 3 中使用newline=''打开文件(Python 2 中为 'rb' 或 'wb')。

File I/O neutral solution:文件 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

This should help.这应该有帮助。 This was written using python 2.7 so if you have any problems running it in 3.x let me know and I can try to help.这是使用 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

Here's a solution but it's a bit long.这是一个解决方案,但它有点长。 Basically I would write all the values in the csv to a list, then remove three value from the list and write to the csv until there's no values left.基本上我会将 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

I'd recommend checking out Pandas I find it a lot easier to manipulate csvs with it, but it's not in the standard library.我建议查看Pandas我发现用它操作 csvs 更容易,但它不在标准库中。

What you want to do is read in the data from the file, then split it into individual elements.您想要做的是从文件中读取数据,然后将其拆分为单个元素。 Once you have it in individual elements you can put them in groups of three and write to your output file.一旦你在单个元素中拥有它,你可以将它们分成三个一组并写入你的输出文件。

Something like this should work:这样的事情应该工作:

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')

I wrote a short program that I think does what you wanted:我写了一个简短的程序,我认为它可以满足您的需求:

It reads all lines from the reader file and then just insert them into the writer file 3 by 3 :)它从读取器文件中读取所有行,然后将它们插入到写入器文件 3 中 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()

A four-line solution without the csv module:没有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')

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

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