Python: общий алгоритм для определения столбцов фиксированной длины - PullRequest
0 голосов
/ 11 февраля 2011

Я пытаюсь написать универсальную функцию, чтобы иметь возможность читать файл фиксированной длины. Я мог бы пройтись и вручную посчитать длину между столбцами, а затем прочитать файл, но мне было интересно, есть ли способ сделать это программно.

Я вижу, что нужно сделать, но я не уверен, как правильно это сделать ...

Если у меня есть файл вроде:

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

Все заголовки «выровнены по правому краю» и разделены пробелами (а не символами табуляции), поэтому мне просто нужно считать от StartIndex до последнего символа, и это длина моего столбца.

Есть ли простой способ добиться этого в python? Результирующий объект будет список длин столбцов

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

Ответы [ 3 ]

3 голосов
/ 11 февраля 2011

Однострочник с использованием регулярных выражений:

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

Пояснение:

re.split разбивает строку во всех точках, где совпадает регулярное выражение. Регулярное выражение, которое я использую (другие были бы возможны), имеет группу «lookbehind» (?<=[^ ]), которая означает «предшествует непробел», а затем пробел, поэтому совпадает с пробелами, которые предшествуют непробелами. Это разделит строку на заголовки столбцов, а затем мы просто возьмем длины результирующих строк.

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

2 голосов
/ 11 февраля 2011

Используя модуль re, вы можете сделать

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]

(Обратите внимание, что ширина столбцов немного отличается от цифр, которые вы указали в своем ответе, но на самом деле я не совсем понимаю, почему вы 'буду ожидать эти цифры.)

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

Если, как кажется,

  1. Между полями всегда должен быть хотя бы один пробел.
  2. Нет значения поля содержит встроенный пробел.

Затем просто разбейте каждую строку примерно так:

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

Если поле имеет тип int или text, тогда вы можете изменить строку таблицы так:

table = [[(int(field) if all(ch in '0123456789' for ch in field) else field)
          for field in line.strip().split()] 
         for line in f]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...