запись фиксированной ширины, разделенного пробелом вывода CSV в Python - PullRequest
7 голосов
/ 12 апреля 2011

Я хотел бы написать CSV-файл фиксированной ширины, разделенный пробелами и минимально заключенный в кавычки, используя Python csv writer.Пример вывода:

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

Если я использую

writer.writerow (("{0: 15s}". Формат (item1), "{0: 15s)} ". format (item2)))
...

затем, с разделителем пробела, форматирование прерывается на кавычки или экранирование (в зависимости от константы csv.QUOTE_ *)добавляются из-за пробелов в конце форматирования элементов:

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

Конечно, я могу отформатировать все сам:

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

но тогда нет смысла использовать csv Writer.Кроме того, мне пришлось бы вручную разобраться в тех случаях, когда в элементах есть место и нужно использовать кавычки / экранирование.Другими словами, кажется, что мне понадобится (несуществующая) константа csv "QUOTE_ABSOLUTELYMINIMAL", которая будет действовать как "QUOTE_MINIMAL", но также будет игнорировать конечные пробелы.

Есть ли способ достичь "QUOTE_ABSOLUTELYMINIMAL "или каким-либо другим способом получить CSV-вывод с фиксированной шириной, разделенным пробелом, с помощью модуля CSV в Python?

Причина, по которой мне нужна функция фиксированной ширины в CSV-файле, заключается в лучшей читаемости.Таким образом, он будет обрабатываться как CSV для чтения и записи, но лучше читается благодаря структуре столбцов.Чтение не является проблемой, так как опция csv skipinitialspace заботится о игнорировании лишних пробелов.К моему удивлению, написание кажется проблемой ...

РЕДАКТИРОВАТЬ: я заключаю, что это невозможно достичь с помощью текущего плагина CSV.Это не встроенная опция, и я не могу найти никакого разумного способа достичь этого вручную, так как кажется, что нет никакого способа записать дополнительные разделители в csv-писателе Python без цитирования или экранирования.Таким образом, мне, вероятно, придется написать свой собственный писатель CSV.

Ответы [ 3 ]

8 голосов
/ 05 августа 2011

Основная проблема, с которой вы сталкиваетесь, заключается в том, что csv и fixed-format в основном противоположны представлениям о хранении данных. Заставить их работать вместе - не обычная практика. Кроме того, если у вас есть только кавычки на элементах с пробелами в них, это исключит выравнивание в этих строках:

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

Вам, конечно, нужно добавить все ваши данные одинаковой длины, прежде чем переходить к функции, которая делает все это, или к самой функции. Да, и если у вас есть числовые данные, вам также придется допускать это для заполнения.

2 голосов
/ 13 апреля 2011

Что это делает для вас?Я думаю, что вы действительно пропустили только константу 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')

Это модификация примера диалекта unixpwd в нижней части документации модуля csv.

0 голосов
/ 12 апреля 2011

Этот рецепт активного состояния показывает, как выводить табличные данные в python: http://code.activestate.com/recipes/267662-table-indentation/

Вы можете почерпнуть из этого примера достаточно, чтобы сделать то, что вы хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...