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

Posted

技术标签:

【中文标题】如何将列表转换为每行 N 项的 CSV 文件?【英文标题】:How to transform a list into a CSV file with N items per row? 【发布时间】: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 并获取每个子列表的前三个对象。 How to print several array elements per line to text file的可能重复 【参考方案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')

【讨论】:

以上是关于如何将列表转换为每行 N 项的 CSV 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何将此字典列表转换为 csv 文件?

如何将 csv 文件转换为可作为文本读取的列表列表? Python

将列表转换为 csv 格式时如何修复编码错误?

如何将 csv 字符串转换为 pandas 中的列表?

如何将 csv 字符串转换为 pandas 中的列表?

如何将一个 csv 列转换为 n 个包含相等行且每个文件包含标题作为 id 的 csv 文件?