在Python中编写固定宽度,空格分隔的CSV输出

jvm*_*jvm 7 python csv space fixed-width

我想使用Python的csv编写器编写固定宽度,空格分隔和最低引用的CSV文件.输出的一个例子:

item1           item2  
"next item1"    "next item2"
anotheritem1    anotheritem2  
Run Code Online (Sandbox Code Playgroud)

如果我使用

writer.writerow(("{0:15s}".format(item1),"{0:15s}".format(item2)))
...

然后,使用空格分隔符,由于项目格式的尾随空格,因此添加了引号或转义(取决于csv.QUOTE_*常量),格式化将被破坏:

"item1          " "item2          "
"next item1     " "next item2     "
"anotheritem1   " "anotheritem2   "
Run Code Online (Sandbox Code Playgroud)

当然,我可以自己格式化所有内容:

writer.writerow(("{0:15s} {1:15s}".format(item1,item2)))

但是使用csv编写器并没有多大意义.此外,当空间嵌入到项目中并且应该使用引用/转义时,我必须手动整理这些情况.换句话说,似乎我需要一个(不存在的)"QUOTE_ABSOLUTELYMINIMAL"csv常量,它将充当"QUOTE_MINIMAL",但也会忽略尾随空格.

有没有办法实现"QUOTE_ABSOLUTELYMINIMAL"行为或使用Python的CSV模块获得固定宽度,空格分隔的CSV输出的另一种方法?

我想在CSV文件中使用固定宽度功能的原因是更好的可读性.因此,它将被处理为CSV以供读取和写入,但由于列结构而更易读.读取不是问题,因为csv skipinitialspace选项负责忽略额外的空格.令我惊讶的是,写作似乎是一个问题......

编辑:我得出结论,使用当前的csv插件是不可能实现的.它不是一个内置选项,我看不出任何合理的方法如何手动实现它,因为似乎没有办法由Python的csv编写器编写额外的分隔符而不引用或转义它们.因此,我可能要编写自己的csv编写器.

Eth*_*man 8

您遇到的基本问题是csv和固定格式基本上是数据存储的对立视图.让它们协同工作并不常见.此外,如果您对其中包含空格的项目只有引号,它将会抛弃这些行上的对齐:

testing     "rather hmm "
strange     "ways to    "
"store some " "csv data   "
testing     testing    
Run Code Online (Sandbox Code Playgroud)

重新读取数据会导致错误的结果:

'testing' 'rather hmm '
'strange' 'ways to    '
'store some ' 'csv data   '
'testing' 'testing' ''
Run Code Online (Sandbox Code Playgroud)

注意最后一行末尾的额外字段.鉴于这些问题,我会以你的例子为例

"item1          " "item2          "
"next item1     " "next item2     "
"anotheritem1   " "anotheritem2   "
Run Code Online (Sandbox Code Playgroud)

我发现它非常易读,很容易使用现有的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()
Run Code Online (Sandbox Code Playgroud)

当然,您需要将所有数据填充到相同的长度,或者在获取执行所有这些操作的函数之前,或者在函数本身中填充.哦,如果你有数字数据,你也必须为它做出填充限制.


kan*_*aka 0

此活动状态配方展示了如何在 python 中输出表化数据: http://code.activestate.com/recipes/267662-table-indentation/

您也许能够从该示例中收集到足够的信息来完成您想要的操作。