简体   繁体   English

无法在Python中写入.csv文件中的所有行?

[英]Not able to write to all rows in .csv file in Python?

I'm trying to write to file2.csv file by values from file1.csv file using a keyfile.csv which contains the mapping between two files as the two files don't have the same column order. 我正在尝试使用file2.csv通过file2.csv文件中的值写入file2.csv文件, file1.csv文件包含两个文件之间的映射,因为这两个文件没有相同的列顺序。

def convert():

    Keyfile = open('keyfile.csv', 'rb')
    file1 = open('file1.csv', 'rb')
    file2 = open('file2.csv', 'w')

    reader_Keyfile = csv.reader(Keyfile, delimiter=",")
    reader_file1 = csv.reader(file1, delimiter=",")
    writer_file2 = csv.writer(file2, delimiter=",")
    for row_file1 in reader_file1:
        for row_Keyfile in reader_Keyfile:
            for index_val in row_Keyfile:
                file2.write(row_file1[int(index_val)-1]+',')
    # Closing all the files     
    file2.close()
    Keyfile.close()
    file1.close()

# keyfile structure: 3,77,65,78,1,10,8...
# so 1st column of file2 is 3rd column of file1 ; 
# col2 of file 2 is col77 of file1 and so on

I'm only able to write only one row in file2.csv . 我只能在file2.csv写一行。 It should have as many rows as there are in file1.csv . 它的行数应与file1.csv How do I move to the next row after one row is finished ? 一行结束后如何移动到下一行? I'm assuming Loop should take care of that but that's not happening.What am I doing wrong ? 我假设Loop应该解决这个问题,但是那没有发生。我在做什么错?

You have two problems. 你有两个问题。

  1. You should only read keyfile once and build a dict out of the mapping 您应该只读取一次密钥文件并根据映射构建字典
  2. You need to write a \\n at the end of each line of your output file 您需要在输出文件的每一行末尾写一个\\n

I am assuming the KeyFile is just one row, giving the mappings for all rows. 我假设KeyFile只是一行,给出了所有行的映射。 Something like the following should work: 类似于以下内容的东西应该起作用:

def convert():
    with open('keyfile.csv') as Keyfile, open('file1.csv', 'r') as file1, open('file2.csv', 'wb') as file2:
        mappings = next(csv.reader(Keyfile, delimiter=","))
        mappings = [int(x)-1 if x else None for x in mappings]

        reader_file1 = csv.reader(file1, delimiter=",")
        writer_file2 = csv.writer(file2, delimiter=",")

        for row_file1 in reader_file1:
            row = [''] * len(mappings)
            for from_index, to_index in enumerate(mappings):
                if to_index != None:
                    row[to_index] = row_file1[from_index]
            writer_file2.writerow(row)

It assumes column mappings start from 1. 假定列映射从1开始。

Your nested looping is problematic as others mentioned. 正如其他人所提到的,嵌套循环是有问题的。 Instead, create the mapping outside of the row iteration, then write the rows based on the mapping. 而是在行迭代之外创建映射,然后根据该映射写入行。 I use a dict object for this. 我为此使用dict对象。

import csv

Keyfile = open('keyfile.csv', 'rb')
file_out = csv.reader(open('file1.csv', 'rb'), delimiter=",")
file_in = csv.writer(open('file2.csv', 'w'), delimiter=",")

mapDict = {}

# the first line in KeyFile convert to dict
reader = csv.reader(Keyfile, delimiter=',')
for i, v in enumerate(reader.next()):
    if v != ' ':
        mapDict[i] = int(v)


# re-index the row in file_in based on mapDict
for row in file_out:
    file_in.writerow([row[c] for c in mapDict.values()])

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

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