打开一个CSV文件,跳到第6行,将不同标题的数据逐行写入不同的文件

2024-04-28 17:53:53 发布

您现在位置:Python中文网/ 问答频道 /正文

Edit:https://stackoverflow.com/a/644314/8520561没有解决问题,或者是因为我掉了一个键,代码错了,我不明白,或者是以上所有的问题。你知道吗

我已经编辑了下面的脚本结尾,以显示什么给了我正确的答案。你知道吗

作为强迫自己学习python的练习,我想用它来创建一些有用的东西。我正在尝试在python中尽可能正确地完成它。不允许作弊,比如使用Unix命令行工具来避免几行python。你知道吗

我想打开一个CSV文件,从输入文件的第7行开始,用不同的头将它写入一个不同的CSV文件。第6行定义了输入标题。我以为他们总是一样的。你知道吗

输入头在CS\u头中,输出头在YNAB\u头中

# Define the headers for the bank statement input file
CS_headers = ['Booking Date', 'Text', 'Debit', 'Credit', 'Balance']
# Define the headers for the YNAB output file
YNAB_headers = ['Date', 'Payee', 'Memo', 'Inflow', 'Outflow']

我想要地图

'Booking Date''Date'
'Text''Payee'
'Debit''Outflow'
'Credit''Inflow'
从输出中删除'Balance'

有时

把某物注入'Memo'字段。你知道吗

脚本输出

$ ./cs_statement.py
Traceback (most recent call last):
  File "./cs_statement.py", line 52, in <module>
    statementwriter.writerow(row)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/csv.py", line 155, in writerow
    return self.writer.writerow(self._dict_to_list(rowdict))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/csv.py", line 151, in _dict_to_list
    + ", ".join([repr(x) for x in wrong_fields]))
ValueError: dict contains fields not in fieldnames: 'Booking Date', 'Debit', 'Balance', 'Text', 'Credit'

输入文件的前几行。你知道吗

$ $ head -8 statement.csv | cat -n
 1  Created on  30.06.2019 12:14:06 CEST
 2  Bookings
 3  Account,"Private account Bonviva Silver,CH72 0483 5028 1234 5678 0,John Doe, Swisstown"
 4  Balance,"CHF 37,924.81"
 5  Booking Entries from 05.07.2018 - 30.06.2019
 6  Booking Date,Text,Debit,Credit,Balance
 7  28.06.2019,"Payment domestic - ISR ,Salt Mobile SA ,AID5c9fdb2ae4744b9ba7ad22afbd16b17d,Salt Mobile SA,Rue du Caudray 4 1020 Renens 1,UBS Switzerland AG,Bahnhofstrasse 45 8098 Zürich CH ",19.00,,37924.81
 8  28.06.2019,"Payment domestic - ISR ,Mortgage Q2 2019 ,DNCS-20190615-IXN0-TXN0,Mortgage Q2 2019,SP-29312538-0,SWISS LIFE AG,ZUERICH ",806.25,,

现在的剧本。你知道吗

#!/usr/local/bin/python3

import csv
import re


# Credit Scheiß's idea of a CSV file includes:
# 1 the first 3 characters are non-ASCII
# 2 the CSV headers are on line 6
# 3 the last line is a totals line
def skip_lines(handle, numlines):
    for i in range(0, numlines):
        handle.readline()


lines_to_skip = 5
in_filename = 'bankstatement.csv'
out_filename = 'bankstatement.YNAB.csv'

# Define the headers for the bank statement input file
CS_headers = ['Booking Date', 'Text', 'Debit', 'Credit', 'Balance']
# Define the headers for the YNAB output file
YNAB_headers = ['Date', 'Payee', 'Memo', 'Inflow', 'Outflow']

# open the file and skip to the heaeder line
statement_infile_handle = open(in_filename, 'r', newline='')
skip_lines(statement_infile_handle, lines_to_skip)

# what kind of CSV file am I?
dialect = csv.Sniffer().sniff(statement_infile_handle.read(10240))
statement_infile_handle.seek(0)
skip_lines(statement_infile_handle, lines_to_skip)

# define a CSV reader object to, er, read the file
statementreader = csv.DictReader(statement_infile_handle,
                                 fieldnames=CS_headers, restkey='',
                                 dialect=dialect)

# define a CSV writer, so I stand a chance of getting at the headers
statement_outfile_handle = open(out_filename, 'w', newline='')
# statementwriter = csv.writer(statement_outfile_handle)
statementwriter = csv.DictWriter(statement_outfile_handle,
                                 fieldnames=YNAB_headers, restval='',
                                 dialect=dialect)
statementwriter.writeheader()

# This part
#    for row in statementreader:
#        statementwriter.writerow(row)
#
# was replaced with this, to solve the problem.
keymap = {'Booking Date': 'Date', 'Text': 'Payee',
         'Debit': 'Outflow', 'Credit': 'Inflow'}
for row in statementreader:
outrow = {keymap[key]: value for key, value in row.items() if key in
          keymap}
statementwriter.writerow(outrow)

Tags: csvthetoinfordatelinefile
1条回答
网友
1楼 · 发布于 2024-04-28 17:53:53

你想把旧的键映射到新的键,当你对自己说I want to map something时,想想字典。你需要为每一行编一本新字典。你知道吗

...
newkeys = {'Booking Date':'Date','Text':'Payee',
           'Debit':'Outflow','Credit':'Inflow'}

for row in statementreader:
    newrow = {newkeys[key]:value for key,value in row.items() if key in newkeys}
    statementwriter.writerow(newrow)

也可以这样写:

for row in statementreader:
    newrow = {}
    for key,value in row.items():
        if key in newkeys:
            newrow[newkeys[key]] = value
    statementwriter.writerow(newrow)

或者

for row in statementreader:
    newrow = {}
    for key,value in row.items():
        try:
            newrow[newkeys[key]] = value
        except KeyError:
            pass
    statementwriter.writerow(newrow)

相关问题 更多 >