开发者

Python: Generic Algorithmic to determine fixed length columns

开发者 https://www.devze.com 2023-02-10 03:49 出处:网络
I am trying to write a generic function to be able to read a fixed length file.I could go through and hand count the length between columns, and then read the file, but I was wondering if there was a

I am trying to write a generic function to be able to read a fixed length file. I could go through and hand count the length between columns, and then read the file, but I was wondering if there was a way to do it programmatically开发者_开发知识库.

I can see what needs to be done, but I am not sure the proper way to do it...

If I have a file like:

 ColA  ColB       ColC      FinalCol
    1    22         23 ColumnsCnBTxt
  213     1          2             2
11213 11111 1234567890             3

All of the headers are "right justified" and seperated by spaces (not tabs), so I basically just need to count from StartIndex to last Character and that is my column length.

Is there any easy way to achieve this in python? The resulting object would be a list of column lengths

header_line = " ColA  ColB       ColC      FinalCol"
result = get_header_information(header_line)
#result  = (5,5, 10, 13)


One-liner using regex splits:

>>> map(len, re.split(r"(?<=[^ ]) ", head))
[5, 5, 10, 13]

Explanation:

re.split splits a string at all points where a regular expression matches. The regular expression I use (others would be possible) has a lookbehind group (?<=[^ ]) which means "preceded by a non-space" and then a space, so matches spaces which are preceded by non-spaces. This will split the string into the column headers, and then we simply take the lengths of the resulting strings.

Notice that this is not performance-optimal -- we are making three passes through the string and invoking a regex engine -- but for normal-size strings that's fine.


Using the re module, you could do

header = " ColA  ColB       ColC      FinalCol"
endcols = [m.end() for m in re.finditer("[^ ]+", header)]
widths = [j - i for i, j in zip([0] + endcols, endcols)]
# [5, 6, 11, 14]

(Note that the column widths differ slightly from the numbers you gave in your answer, but I actually don't really understand why you'd expect those numbers.)


If, as it seems,

  1. You always have at least one space between fields.
  2. No field value contains an embedded space.

Then just split each line something like:

f = file('filename', 'r')
table = [line.strip().split() for line in f]
f.close()

If a field is either an int or text then you could modify the table line to become:

table = [[(int(field) if all(ch in '0123456789' for ch in field) else field)
          for field in line.strip().split()] 
         for line in f]
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号