Как создать копию файла с удалением нескольких диапазонов столбцов в python3 - PullRequest
0 голосов
/ 09 июля 2020

Я хочу сделать копию файла с записями фиксированной ширины с удалением нескольких диапазонов чисел c. Например, файл имеет фиксированную ширину записей длиной 1600, и я хочу сохранить столбцы 0-83, 89-1517, 1526-конец. Это для использования в более крупной проблеме, отдельные утилиты, такие как cut и awk, здесь не помогут.

У меня есть это, которое я применяю к каждой строке / записи; он работает нормально, интересно, есть ли что-нибудь явно лучше. больше похоже на

 # hypothetical
 cut(line, [ [84,88], [1519, 25] ])

ДОПОЛНЕНИЕ

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

def cut(line, cuts):
    sorted_cuts = sorted(cuts, key=lambda x: x[0])
    
    return ''.join(line[slice(keep_start, keep_end)]
                   for keep_start, keep_end in zip(
                           [None] + [cut_end for cut_start, cut_end in sorted_cuts],
                           [cut_start for cut_start, cut_end in sorted_cuts] + [None]))


origline = "0123456789"

assert (cut(origline, [[1,2], [3,4]]) ==
        cut(origline, ([3,4], (1,2))) ==
        cut(origline, [[3,4], [1,2]]))

print(cut(origline, [[1,2], [3,4]]))

1 Ответ

1 голос
/ 09 июля 2020

Вот реализация вашей гипотетической функции cut.

def cut(line, cuts):
    
    return ''.join(line[slice(keep_start, keep_end)]
                   for keep_start, keep_end in zip(
                           [None] + [cut_end for cut_start, cut_end in cuts],
                           [cut_start for cut_start, cut_end in cuts] + [None]))

print(cut('abcdefghijklmnopqrstuvwxyz', [[1,3], [9,10]]))

дает:

adefghiklmnopqrstuvwxyz

(bc и j были вырезаны)

Итак:

  • сохраняемый фрагмент идет от начала до начала первого разреза,
  • фрагмент, который нужно сохранить, идет от конца первого разреза к началу второго разреза
  • ...
  • последний кусок, который нужно сохранить, идет от конца последнего разреза до конца строки

[None] + [cut_end for cut_start, cut_end in cuts] - начало каждого сохраняемого фрагмента, в этом примере [None, 3, 10]

[cut_start for cut_start, cut_end in cuts] + [None] - это конец каждого фрагмента, который необходимо сохранить, в этом примере [1, 9, None]

где None означает начало / конец строки, используемой встроенной функцией slice.

Примечание: для реализации сокращений, приведенных в вашем примере, вы должны предоставить аргументы этой cut функции как:

 cut(line, [[84, 89], [1519, 1526]])

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

Если вы действительно хотите, чтобы не приходилось делать это (чтобы получить точно функцию cut, которую вы описали выше), то в приведенном выше коде вы замените:

[cut_end for cut_start, cut_end in cuts]

на:

[cut_end + 1 for cut_start, cut_end in cuts]

Для удобства здесь - это полный код функции в этом случае и вызывающий код, который вы использовали бы в своем примере:

def cut(line, cuts):
    
    return ''.join(line[slice(keep_start, keep_end)]
                   for keep_start, keep_end in zip(
                           [None] + [cut_end + 1 for cut_start, cut_end in cuts],
                           [cut_start for cut_start, cut_end in cuts] + [None]))

print(cut(line, [[84, 88], [1519, 1525]])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...