1

I have columnar data in which a column of data ranges widely in width. I would like to display this data in a monospace font, for easy viewing while additionally retaining the capabilities of parsing that data with common csv handlers.

I am willing to accept that a strip/trim operations may need to be done by the parsing lib and I am not worried about leading/trailing white space being preserved.

How can I write a csv with fixed width data columns? Is this possible with the csv module?

In Open/Libre Office terms, this is called "Fixed column width" in the Export Text File options.

Example

data = [
    ('Brown Fox Jumps Over', 'Lorem ipsum',),
    ('The Lazy', 'dolor sit amet,',),
    ('Dog', 'consectetur adipiscing elit.',),
]

Desired output

"Header 1            ", "Header 2                    ",
"Brown Fox Jumps Over", "Lorem ipsum                 ",
"The Lazy            ", "dolor sit amet,             ",
"Dog                 ", "consectetur adipiscing elit.",

Chiefly I'm looking for a tool to scan a dataset for its widest values and format then entire column to that width for all columns because writing one myself inline feels inappropriate.

martineau
  • 119,623
  • 25
  • 170
  • 301
ThorSummoner
  • 16,657
  • 15
  • 135
  • 147
  • 2
    If the columns have a fixed width, you wouldn't need a comma to separate them. – chepner Apr 21 '15 at 17:26
  • Do you mean that the text file would have fixed-width columns, or do you mean that the presentation in Excel or LibreOffice would be fixed-width? – Robᵩ Apr 21 '15 at 17:27
  • As @chepner suggests, if it truly is a CSV file, then the `csv` module should handle it. If you tried it and it didn't work, post the details. – Scott Hunter Apr 21 '15 at 17:27
  • @ScottHunter - I think the OP is using `csv` as a generic term. What it sounds like he actually wants is a fixed-width file. OTOH, I'm not certain enough based on his question to go in and edit it for clarity. He may actually want a CSV file with fixed-width columns. :-D – Deacon Apr 21 '15 at 17:33

1 Answers1

3

Use str.format?

In [1]: '{0: <10}'.format('lorem')
Out[1]: 'lorem     '

In [2]: '{0: <10}'.format('lorem ipsum')
Out[2]: 'lorem ipsum'

Something like,

lines = ['lorem ipsum', 'dolor sit amet']

with open('foo.txt', 'w') as foo:
   for line in lines:
       words = line.split()
       formatted = ' '.join(['{0: <5}'.format(word) for word in words])
       foo.write(formatted + '\n')

$ cat foo.txt
lorem ipsum
dolor sit   amet

You could then use pandas to read it quite elegantly

In [1]: df = pd.read_fwf('foo.txt', colspecs=[(0,5),(6,11),(12,17)], header=None)

In [2]: df
Out[2]:
       0      1     2
0  lorem  ipsum   NaN
1  dolor    sit  amet
ComputerFellow
  • 11,710
  • 12
  • 50
  • 61