2011-04-12 1 views
7

Je voudrais écrire un fichier CSV de largeur fixe, espace délimité et peu cité en utilisant le csv writer de Python. Un exemple de la sortie:écriture de largeur fixe, sortie CSV délimitée par un espace en Python

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

Si je

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

puis, avec le séparateur d'espace, la mise en forme est cassé comme soit des citations ou des évasions (selon la csv.QUOTE_ * constante) sont ajoutés en raison des espaces de fin de le formatage des articles:

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

Bien sûr, je pourrais mettre en forme tout moi-même:

writer.writerow ((. "{0: 15s} {1}: 15s" Format (article1, article2)))

mais il n'y a pas grand intérêt à utiliser le graveur csv. De plus, je devrais trier manuellement ces cas lorsque l'espace est incorporé dans les éléments et que quoting/escape devrait être utilisé. En d'autres termes, il semblerait que j'aurais besoin d'une constante csv "QUOTE_ABSOLUTELYMINIMAL" (non existante) qui agirait comme la variable "QUOTE_MINIMAL" mais ignorerait aussi les espaces de fin.

Existe-t-il un moyen d'obtenir le comportement "QUOTE_ABSOLUTELYMINIMAL" ou un autre moyen d'obtenir une sortie CSV délimitée par un espace et de largeur fixe à l'aide du module CSV de Python?

La raison pour laquelle je veux la fonctionnalité de largeur fixe dans un fichier CSV est une meilleure lisibilité. Il sera donc traité en CSV à la fois en lecture et en écriture mais mieux lisible en raison de la structure de la colonne. La lecture n'est pas un problème car l'option skipinitialspace de csv prend soin d'ignorer les espaces supplémentaires. À ma grande surprise, l'écriture semble être un problème ...

EDIT: Je conclus qu'il est impossible de réaliser avec le plugin csv actuel. Ce n'est pas une option intégrée et je ne vois pas de méthode raisonnable pour la réaliser manuellement car il semble qu'il n'y ait aucun moyen d'écrire des délimiteurs supplémentaires par l'auteur csv de Python sans les citer ni les échapper. Ainsi, je vais probablement écrire mon propre csv.

Répondre

0

Cette recette d'état actif montre comment les données de table-isée sortie en python: http://code.activestate.com/recipes/267662-table-indentation/

Vous pourriez être en mesure de glaner assez de cet exemple pour faire ce que vous voulez.

+0

Merci pour votre réponse. Cependant, le code que vous liez n'utilise pas le plugin csv de Python et n'est pas destiné à la sortie csv. Il est certainement possible d'écrire mon propre csv mais j'espérais qu'il y avait un moyen d'utiliser celui de Python dans ce but ... – jvm

2

Qu'est-ce que cela fait pour vous? Je pense que vous ne manquiez que la constante 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') 

Il est une modification de l'exemple dialecte unixpwd au bas du module csv docs.

+1

Je ne vois pas comment cet exemple de lecteur pourrait résoudre le problème de l'écriture? csv.QUOTE_NONE n'aide pas non plus - les espaces de fin des objets sont échappés en écriture dans ce cas. – jvm

8

Le problème de base que vous rencontrez est que csv et fixed-format sont des vues opposées du stockage de données. Les faire travailler ensemble n'est pas une pratique courante.En outre, si vous avez seulement des citations sur les articles avec des espaces en eux, il se débarrasser de l'alignement sur les lignes:

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

lecture que les données de retour dans les résultats dans un mauvais résultats ainsi:

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

Notez le champ supplémentaire à la fin de la dernière ligne. Compte tenu de ces problèmes, je vais avec votre exemple de

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

que je trouve très lisible, est facile à générer avec la bibliothèque csv existante et obtient correctement analysé lors de la lecture avant. Voici le code que j'utilisé pour générer il:

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

Vous, bien sûr, besoin d'avoir toutes vos données rembourrées à la même longueur, soit avant d'arriver à la fonction qui fait tout cela, ou dans la fonction elle-même. Oh, et si vous avez des données numériques, vous devrez également prévoir des tolérances de remplissage.

Questions connexes