Лучший способ написать этот список понимания? - PullRequest
2 голосов
/ 02 июля 2010

Я анализирую строку, у которой нет разделителя, но есть определенные индексы, где поля начинаются и заканчиваются.Вот мое понимание списка для создания списка из строки:

field_breaks = [(0,2), (2,10), (10,13), (13, 21), (21, 32), (32, 43), (43, 51), (51, 54), (54, 55), (55, 57), (57, 61), (61, 63), (63, 113), (113, 163), (163, 213), (213, 238), (238, 240), (240, 250), (250, 300)]
s = '4100100297LICACTIVE  09-JUN-198131-DEC-2010P0         Y12490227WYVERN RESTAURANTS INC                            1351 HEALDSBURG AVE                                                                                 HEALDSBURG               CA95448     ROUND TABLE PIZZA                                 575 W COLLEGE AVE                                 STE 201                                           SANTA ROSA               CA95401               '
data = [s[x[0]:x[1]].strip() for x in field_breaks]

Любая рекомендация о том, как улучшить это?

Ответы [ 4 ]

7 голосов
/ 02 июля 2010

Вы можете использовать распаковку кортежа для кода уборщика:

data = [s[a:b].strip() for a,b in field_breaks]
7 голосов
/ 02 июля 2010

Вы можете сократить список field_breaks пополам, выполнив:

field_breaks = [0, 2, 10, 13, 21, 32, 43, ..., 250, 300]
s = ...
data = [s[x[0]:x[1]].strip() for x in zip(field_breaks[:-1], field_breaks[1:])]
3 голосов
/ 02 июля 2010

Честно говоря, я не нахожу подход «анализ по столбцам» очень читабельным, и я ставлю под сомнение его удобство обслуживания (за исключением одной ошибки и т. П.).Хотя я уверен, что в этом случае понимание списка очень действенно и эффективно, и предлагаемое решение на основе zip имеет приятную функциональную настройку.

Вместо этого я собираюсь выбросить софтболы отсюдав левом поле, поскольку предполагается, что списочные выражения должны частично сделать ваш код более декларативным.Для чего-то совершенно другого, рассмотрим следующий подход, основанный на модуле pyparsing:

def Fixed(chars, width):
    return Word(chars, exact=width)

myDate = Combine(Fixed(nums,2) + Literal('-') + Fixed(alphas,3) + Literal('-')
                 + Fixed(nums,4))

fullRow = Fixed(nums,2) + Fixed(nums,8) + Fixed(alphas,3) + Fixed(alphas,8)
          + myDate + myDate + ...

data = fullRow.parseString(s)
# should be ['41', '00100297', 'LIC', 'ACTIVE  ', 
#            '09-JUN-1981', '31-DEC-2010', ...]

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

someId = Fixed(nums,2)
someOtherId = Fixed(nums,8)
recordType = Fixed(alphas,3)
recordStatus = Fixed(alphas,8)
birthDate = myDate
issueDate = myDate
fullRow = someId + someOtherId + recordType + recordStatus
          + birthDate + issueDate + ...

Теперь такой подход, вероятно, не собирается побивать рекорды скорости на суше.Но, святая корова, тебе не будет легче читать и поддерживать?

0 голосов
/ 02 июля 2010

Вот способ использования map

data = map(s.__getslice__, *zip(*field_breaks))
...