Little direction please Python MySQL
Tim Chase
python.list at tim.thechases.com
Mon Nov 17 06:52:31 EST 2008
>> Files are fixed format no field delimiters, fields are position and
>> length records are terminated by newline.
>
> Assuming no COMPUTATIONAL fields, it should be easy enough to split each line up into fixed-length pieces, e.g. assuming a simple example
>
> 01 Sample-Record.
> 02 Field-1 pic XXX.
> 02 Field-2 pic XXXX.
> 02 Field-3 pic XXXXX.
>
> then a Python sequence that read one line's worth of fields might be
>
> line = infile.read()
> (field_1, field_2, field_3) = (line[0:3], line[3:7], line[7:12])
A recent posting on the list offered an elegant solution to this
with a function something like
def splitter(s, *lens):
offset = 0
pieces = []
for length in lens:
pieces.append(s[offset:offset+length])
offset += length
return pieces
which could then be used to simplify that to
(f1, f1, f3) = splitter(line, 3, 4, 5)
It may not be quite so significant with just 3 items, but the OP
mentioned having a large number of items in each record. One
could even use something like a mapping for this. Something like:
field_lens = [
("field1", 3),
("field2", 4),
("field3", 5),
# stacks more
]
fields = dict(zip(
(name for name, _ in field_lens),
splitter(line, *[length for _, length in field_lens])
))
something = "Whatever %s you want" % fields["field2"]
If you like this method, you can even make a more targeted
splitter() function and add some function mappings like
field_lens = [ # somewhat similar to your Cobol masks
("field1", 3, str),
("field2", 4, int),
("field3", 5, float),
("field4", 17, lambda s: s.strip().upper() ),
# stacks more
]
def splitter(s, field_lens):
pieces = {}
offset = 0
for name, length, fn in field_lens:
pieces[name] = fn(s[offset:offset+length])
offset += length
return pieces
bits = splitter(line), field_lens)
# do addition of int+float rather than string concat
print bits["field2"] + bits["field3"]
-tkc
More information about the Python-list
mailing list