在Python中编写固定宽度,空格分隔的CSV输出 [英] writing fixed width, space delimited CSV output in Python

查看:407
本文介绍了在Python中编写固定宽度,空格分隔的CSV输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Python的csv writer写一个固定宽度,空格分隔和最小引用的CSV文件。
输出示例:

  item1 item2 
next item1next item2
anotheritem1 anotheritem2

如果我使用



< >

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

...


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

 item1item2
next item1 next item2
anotheritem1anotheritem2

当然, :


writer.writerow(({0:15s} {1:15s}。format(item1,item2))) / p>

但是使用csv writer没有太多意义。此外,我必须手动整理这些情况下,当空间嵌入在项目,并应使用引号/转义。换句话说,它似乎需要一个(不存在)QUOTE_ABSOLUTELYMINIMALcsv常量,将作为QUOTE_MINIMAL,但也会忽略尾随空格。



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



我想要的原因CSV文件中的固定宽度功能更好的可读性。所以它将被处理为CSV读取和写入,但更好的可读性由于列结构。阅读不是一个问题,因为csv skipinitialspace选项照顾忽略额外的空间。令我惊讶的是,写作似乎是一个问题...



编辑:我认为这是不可能实现与当前csv插件。它不是一个内置的选项,我不能看到任何合理的方式如何手动实现它似乎没有办法写入额外的分隔符由Python的csv作者没有引用或逃脱他们。因此,我可能必须写我自己的csv writer。

解决方案

你遇到的基本问题是csv和固定格式基本上是相反的数据存储视图。让他们一起工作不是一个常见的做法。此外,如果您只对其中带有空格的项目有引号,它将会抛弃这些行上的对齐方式:

 测试,而是hmm
strange到
存储一些csv数据
测试测试

读取该数据导致错误的结果:

 'testing' 
'
''
''
''
'存储一些'csv数据'
'测试''测试'''
/ pre>

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

 item1item2
next item1 next item2
anotheritem1anotheritem2

使用现有的csv库生成,并在读回时正确解析。下面是我用来生成它的代码:

  import csv 

class SpaceCsv(csv.Dialect):
csv格式导出表
delimiter = None
doublequote = True
escapechar = None
lineterminator ='\\\
'
quotechar =''
skipinitialspace = True
quoting = csv.QUOTE_MINIMAL
csv.register_dialect('space',SpaceCsv)

data =(
('testing','rather hmm'),
('strange','ways to' ,'csv data'),
('testing','testing'),

temp = open(r'c:\tmp\fixed.csv' )
writer = csv.writer(temp,dialect ='space')
数据中的行:
writer.writerow(row)
temp.close()

当然,您需要将所有数据填充到相同的长度,所有这一切,或在函数本身。哦,如果你有数字数据,你也必须为此填充津贴。


I would like to write a fixed width, space delimited and minimally quoted CSV file using Python's csv writer. An example of the output:

item1           item2  
"next item1"    "next item2"
anotheritem1    anotheritem2  

If I use

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

then, with the space delimiter, the formatting is broken as either quotes or escapes (depending on the csv.QUOTE_* constant) are added due to the trailing spaces of the items formatting:

"item1          " "item2          "
"next item1     " "next item2     "
"anotheritem1   " "anotheritem2   "

Of course, I could format everything myself:

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

but then there is not much point in using the csv writer. Also, I would have to sort out manually those cases when the space is embedded in the items and quoting/escaping should be used. In other words, it seems I would need a (non-existing) "QUOTE_ABSOLUTELYMINIMAL" csv constant that would act as the "QUOTE_MINIMAL" one but would also ignore trailing spaces.

Is there a way to achieve the "QUOTE_ABSOLUTELYMINIMAL" behaviour or another way to get a fixed width, space delimited CSV output using Python's CSV module?

The reason why I want the fixed-width feature in a CSV file is a better readability. So it will be processed as CSV for both reading and writing but better readable due to the column structure. Reading is not a problem as the csv skipinitialspace option takes care of ignoring the extra spaces. To my surprise, writing seems to be a problem...

EDIT: I conclude it is impossible to achieve with the current csv plugin. It is not a built-in option and I cannot see any reasonable way how to achieve it manually as it seems there is no way to write extra delimiters by the Python's csv writer without quoting or escaping them. Thus, I will probably have to write my own csv writer.

解决方案

The basic problem you are running into is that csv and fixed-format are basically opposing views of data storage. Making them work together is not a common practice. Also, if you only have quotes on the items with spaces in them, it will throw off the alignment on those rows:

testing     "rather hmm "
strange     "ways to    "
"store some " "csv data   "
testing     testing    

Reading that data back in results in wrong results as well:

'testing' 'rather hmm '
'strange' 'ways to    '
'store some ' 'csv data   '
'testing' 'testing' ''

Notice the extra field at the end of the last row. Given these problems, I would go with your example of

"item1          " "item2          "
"next item1     " "next item2     "
"anotheritem1   " "anotheritem2   "

which I find very readable, is easy to generate with the existing csv library, and gets correctly parsed when read back in. Here's the code I used to generate it:

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()

You will, of course, need to have all your data padded to the same length, either before getting to the function that does all this, or in the function itself. Oh, and if you have numeric data you'll have to make padding allowances for that as well.

这篇关于在Python中编写固定宽度,空格分隔的CSV输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆