【问题标题】:Reading CSV results in nested list and needs repairs - more efficient way needed在嵌套列表中读取 CSV 并需要修复 - 需要更有效的方式
【发布时间】:2020-05-13 06:57:35
【问题描述】:

问题: 我的程序读取一个 CSV 文件并生成一个嵌套列表(因为没有换行符),之后我需要“修复”该列表,然后才能进一步操作。该代码有效,但我正在努力寻找更有效的方法,并对任何建议感兴趣。

详情:

我的程序读取具有以下格式的 CSV 文件:

hakcke39475728,fjfjalcl689920,vjgjvkv848291, ...

所以每个项目都包含字母和数字,以逗号作为分隔符,中间没有新行。我使用 csv 读取文件并将结果放入列表中:

import csv

result = []
with open("input.csv", "r", newline="") as f:
    reader = csv.reader(f, delimiter=",", quotechar='"')
    result = list(reader)

由于没有换行符,结果是一个嵌套列表,格式如下:

[['hakkke39475728', 'fjfjalcl689920', 'vjgjvkv848291', '...'], []]

在此之后,我需要“清理”并执行一个额外的步骤 - 一个 for 循环 - 以取消嵌套列表:

output_final = [] 
for item in result[0]:
    output_final.append(item)

要最终得到我需要的输出:

['hakcke39475728', 'fjfjalcl689920', 'vjgjvkv848291', '...']

什么是更有效的方法?

我不知道如何以不同的方式读取 CSV,以免生成嵌套列表。 AFAIK 无法将逗号设置为 EOL 字符(这将解决我的问题,因为我在输入值之间没有行尾。

可能相关的问题:

  • 我找到了this question,但这是关于以不同的方式编写 CSV,而不是读取它,在我的情况下是不可能的。
  • This one 要求嵌套列表而不是想要摆脱它,但是没有办法对解决方案进行逆向工程。

【问题讨论】:

  • 您不能简单地使用 list(reader)[0] 访问您的结果吗?
  • 好的,谢谢。这就是我现在正在做的事情。我添加了我修复的代码sn-p,正是这个。我只是想知道这是否真的是最有效的方法,或者我在这里遗漏了什么。
  • 您似乎有一个由逗号分隔的单个条目的文件,所以open("input.csv", "r", newline="").split(',') 可能就足够了。
  • 您实际上不需要 for 循环。只需 output_final = list(reader)[0] 即可。另外,snakecharmerb 对 csv 阅读器的更改可能会更干净。
  • JasonChia - 是的,你的建议有效。谢谢。 @snakecharmerb - 尝试您的建议时出现错误:AttributeError: '_io.TextIOWrapper' object has no attribute 'split' - 需要调查一下,因为我无法找到正确的修复方法现在。有什么建议吗?

标签: python performance csv


【解决方案1】:

在此之后,我需要“清理”并执行一个额外的步骤 - 一个 for 循环 - 以取消嵌套列表:

无需将项目一一复制到新列表中。

output_final = result[0]

或者/在更多上下文的情况下,假设您的 CSV 文件实际上只包含一行数据:

import csv

with open("input.csv", "r", encoding="utf8", newline="") as f:
    reader = csv.reader(f, delimiter=",", quotechar='"')
    result = next(reader)

csv 阅读器是一个迭代器 - 它迭代 CSV 文件中的行。通常你会在for 循环中使用迭代器:

    for row in reader:
        ...

与列表的主要区别在于您不能直接访问迭代器的元素:reader[0] 不起作用。但是next() 函数每次调用它时都会从迭代器中检索下一个元素。

在这种情况下,next(reader) 仅被调用一次,因此您将获得数据的第一“行”。

关于newline="" 的注释。这并不意味着没有换行符。这意味着csv 模块将为您处理换行符并自动适应 Windows、Mac 或 *nix 样式的换行符。在处理csv 模块时,您应该始终使用newline="" 打开文件。

【讨论】:

  • 谢谢!使用 next(reader) 就可以了,它完全创建了我需要的列表。
  • @ladyfrauke 在处理 CSV 数据的其他情况下,请记住 next()。例如,您可以使用它来跳过 CSV 阅读器中的标题行 - next(reader) 将阅读器前进一格,然后您可以调用 for row in reader: 来查看其余数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-11
  • 2012-05-26
相关资源
最近更新 更多