【问题标题】:Read csv starting with leading spaces从前导空格开始读取 csv
【发布时间】:2017-06-16 14:11:27
【问题描述】:

我有一个逗号分隔的文件(来自第三方),其中每行以空格开头和结尾,字段用双引号引起来,文件以只有空格的行结尾。

 "first_name";"last_name" 
 "John";"Doe" 
 "Anita";"Doe"  

我尝试使用以下代码阅读此内容。

import csv
import json

def read_csv(filename):
    result = []
    with open(filename, 'r', encoding='utf-8') as f:
        csv_reader = csv.reader(f, delimiter=';', quotechar='"')
        for line_index, line in enumerate(csv_reader):
            if line_index == 0:
                header = line
                continue
            result.append(dict(zip(header, line)))
    return result

if __name__ == '__main__':
    contents = read_csv('test.txt')
    print(json.dumps(contents, indent=4, sort_keys=4))

这是我的预期结果:

[
    {
        "first_name": "John",
        "last_name ": "Doe "
    },
    {
        "first_name": "Anita",
        "last_name ": "Doe "
    }
]

但是,由于前导空格,它总是将双引号作为第一列的一部分,而且它还考虑了最后一行。这是我得到的结果:

[
    {
        " \"first_name\"": " \"John\"",
        "last_name ": "Doe "
    },
    {
        " \"first_name\"": " \"Anita\"",
        "last_name ": "Doe "
    },
    {
        " \"first_name\"": " "
    }
]

如何在解析 csv 之前 去除这些前导和尾随空格?答案here 展示了如何在读取字段后从字段中删除空格,但这在这里并不好,因为我要更改的不是字段的内容,而是字段本身。

顺便说一句:我使用的是 Python 3.5。

编辑

我现在使用以下代码跳过空行:

# Skip empty lines
line = [column.strip() for column in line]
if not any(line):
    continue

【问题讨论】:

    标签: python csv whitespace


    【解决方案1】:

    您可以使用skipinitialspace=True 并使用csv.DictReader(它假定第一行是标题并为您创建名称-> 值的dict,而不是自己手动执行),例如:

    with open(filename) as fin:
        csvin = csv.DictReader(fin, delimiter=';', skipinitialspace=True)
        result = list(csvin)
    

    或者,如果只考虑具有某个值的行(即,最后一行没有值,甚至应该过滤掉迭代空白行),您可以使用:

    result = [row for row in csvin if any(row.values())]
    

    这会给你:

    [{'first_name': 'John', 'last_name ': 'Doe '},
     {'first_name': 'Anita', 'last_name ': 'Doe '}]
    

    使用json.dumps(result, indent=4, sort_keys=4)) 的结果是:

    [
        {
            "first_name": "John",
            "last_name ": "Doe "
        },
        {
            "first_name": "Anita",
            "last_name ": "Doe  "
        }
    ]
    

    【讨论】:

    • 谢谢,这已经有助于字段内的双引号。不过,它仍然给了我第三个元素 first_name=""last_name=None
    • 这可能是因为 SO 删除了我的示例 CSV 的最后一行,除了空格之外是空的。
    • @physicalattraction 如果引号字符串中不需要嵌入新行,那么您可以在将空行输入阅读器之前过滤掉空行,否则,您需要过滤行是否有效或不使用您在行本身中拥有的信息。 (或者只是忽略最后一行......)
    • 我害怕那个。我已经在我的问题中添加了我的解决方案。
    • @physicalattraction 我已经更新了答案,包括一种可能更聪明的方法来处理空白行。这可能是尾随行或中间真正的空白行,它们不是在引用的字符串中嵌入新行的一部分。
    猜你喜欢
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多