特定の位置にある改行を除去し,2行を1行にする(または,リストのふたつの要素をつなげてひとつにする)

たとえばこんなテキストがあるとする.

01 ID = 0001
02 ref = hoge
03 body = "hogehogehugahuga"
04 ID = 0002
05 ref = bura
06 body = "
07 buraburaguruguru"
...

06と07は本来1行なのだが,なぜか改行されてしまっている.
なんとなく構造のあるテキストだが,xmlのような標準的な仕様でもないので既存の方法でパースしたりはできない.
このとき,このテキストの構造は行同士の位置関係と行頭の文字列によって与えられているので,06行目のこの位置の改行は構造を正しくとれなくなる原因になる.

解決法

1行を1要素とするリストにすると,.pop()というメソッドが使える.

Pythonでリスト(配列)の要素を削除するclear, pop, remove, del | note.nkmk.me

# coding: utf-8

import codecs

filename = u'/hoge/huga.txt'

# テキストファイルを読み込み,一行ずつリストに入れる
with codecs.open(filename, 'r', 'utf-8') as fin:
    lines_list_raw = [line.rstrip(u'\r\n') for line in fin]

# 行が特定の形で終わっているとき,その次の行をとってきてつなげて,取り出した次の行をリストから消す
lines_list = [line + lines_list_raw.pop(num + 1) if line == u'body = "' else line for num, line in enumerate(lines_list_raw)]

解説

内包表記で書いている部分を通常のfor文で書くと以下.

lines_list = []
for num, line in enumerate(lines_list_raw):
    if line == u'body = ':
        line = line + lines_list_raw.pop(num + 1)
        lines_list.append(line)
    else:
        lines_list.append(line)

enumerate()は,リストのインデックスと値をタプルで返す関数.
これを使うとfor文で要素とインデックスを簡単に取り出せて便利.

.pop()はリストの組み込みメソッドで,指定したインデックスの要素を返し,リストからその要素を削除する.

雑感

別に特別なことでもない(.pop()は最近知ったが)ことしか書いていないが,よく使うものをどう使えば何ができるのかという工夫を蓄積するとコーディングが少しずつできるようになる気がする.特殊なモジュールを使いこなすとか課題自体が難しいようなことを訓練するとかはもっと先の話だと思う.