在 Python 中编写固定宽度、空格分隔的 CSV 输出
Posted
技术标签:
【中文标题】在 Python 中编写固定宽度、空格分隔的 CSV 输出【英文标题】:writing fixed width, space delimited CSV output in Python 【发布时间】:2011-08-04 01:05:11 【问题描述】:我想使用 Python 的 csv writer 编写一个固定宽度、空格分隔和最少引用的 CSV 文件。 输出示例:
item1 item2
"next item1" "next item2"
anotheritem1 anotheritem2
如果我使用
writer.writerow( ("0:15s".format(item1), "0:15s".format(item2)) ) ...
然后,使用空格分隔符,由于项目格式的尾随空格,格式被破坏,因为添加了引号或转义符(取决于 csv.QUOTE_* 常量):
"item1 " "item2 "
"next item1 " "next item2 "
"anotheritem1 " "anotheritem2 "
当然,我可以自己格式化所有内容:
writer.writerow(("0:15s1:15s".format(item1, item2)))
但是使用 csv 编写器并没有多大意义。此外,当空间嵌入到项目中并且应该使用引用/转义时,我将不得不手动整理这些情况。换句话说,我似乎需要一个(不存在的)“QUOTE_ABSOLUTELYMINIMAL”csv 常量,它可以充当“QUOTE_MINIMAL”,但也会忽略尾随空格。
有没有办法实现“QUOTE_ABSOLUTELYMINIMAL”行为或使用 Python 的 CSV 模块获得固定宽度、空格分隔的 CSV 输出?
我想要 CSV 文件中的固定宽度功能的原因是更好的可读性。因此它将被处理为 CSV 用于读取和写入,但由于列结构,可读性更好。读取不是问题,因为 csv skipinitialspace 选项会忽略多余的空格。令我惊讶的是,写作似乎是一个问题......
编辑:我得出结论,使用当前的 csv 插件是不可能实现的。它不是一个内置选项,我看不到如何手动实现它的任何合理方法,因为似乎没有办法在不引用或转义它们的情况下由 Python 的 csv 编写器编写额外的分隔符。因此,我可能不得不编写自己的 csv 编写器。
【问题讨论】:
【参考方案1】:这个活动状态配方展示了如何在 python 中输出表格化数据: http://code.activestate.com/recipes/267662-table-indentation/
您也许可以从该示例中收集到足够的信息来做您想做的事情。
【讨论】:
感谢您的回答。但是,您链接的代码不使用 Python 的 csv 插件,也不适用于 csv 输出。当然可以编写我自己的 csv 编写器,但我希望有一种方法可以为此目的使用 Python 编写器......【参考方案2】:这对你有什么好处?我认为您确实只是缺少 csv.QUOTE_NONE 常量。
import csv
csv.register_dialect('spacedelimitedfixedwidth', delimiter=' ', quoting=csv.QUOTE_NONE)
with open('crappymainframe.out', 'rb') as f:
reader = csv.reader(f, 'spacedelimitedfixedwidth')
这是对 csv 模块文档底部的 unixpwd 方言示例的修改。
【讨论】:
我看不到这个阅读器示例如何解决编写器问题? csv.QUOTE_NONE 也无济于事 - 在这种情况下,项目的尾随空格在写入时会被转义。【参考方案3】:您遇到的基本问题是 csv 和固定格式在数据存储方面基本上是相反的观点。让它们一起工作并不是一种常见的做法。此外,如果您只在其中包含空格的项目上加上引号,它会破坏这些行的对齐方式:
testing "rather hmm "
strange "ways to "
"store some " "csv data "
testing testing
读回该数据也会导致错误的结果:
'testing' 'rather hmm '
'strange' 'ways to '
'store some ' 'csv data '
'testing' 'testing' ''
请注意最后一行末尾的额外字段。考虑到这些问题,我会选择你的例子
"item1 " "item2 "
"next item1 " "next item2 "
"anotheritem1 " "anotheritem2 "
我觉得它非常易读,很容易使用现有的 csv 库生成,并且在读回时可以正确解析。这是我用来生成它的代码:
import csv
class SpaceCsv(csv.Dialect):
"csv format for exporting tables"
delimiter = None
doublequote = True
escapechar = None
lineterminator = '\n'
quotechar = '"'
skipinitialspace = True
quoting = csv.QUOTE_MINIMAL
csv.register_dialect('space', SpaceCsv)
data = (
('testing ', 'rather hmm '),
('strange ', 'ways to '),
('store some ', 'csv data '),
('testing ', 'testing '),
temp = open(r'c:\tmp\fixed.csv', 'w')
writer = csv.writer(temp, dialect='space')
for row in data:
writer.writerow(row)
temp.close()
当然,您需要将所有数据填充到相同的长度,或者在到达执行所有这些操作的函数之前,或者在函数本身中。哦,如果你有数字数据,你也必须为此留出填充余量。
【讨论】:
以上是关于在 Python 中编写固定宽度、空格分隔的 CSV 输出的主要内容,如果未能解决你的问题,请参考以下文章
在 spark java 中读取具有固定宽度和分隔符的文本文件
查找连续重复单词时的Python后视正则表达式“固定宽度模式”错误