如何将列表转换为每行 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 文件?的主要内容,如果未能解决你的问题,请参考以下文章