

r_file.txtを1行ずつ読み込み、w_file.csvファイル（CSVファイル）にしました。  
目的は実現できておりますが、もっと、コードを短くすることや、もっと改善するべき箇所を  
アドバイスいただければと思います。

r_file.txt↓

[code]

    Tue Nov 11 00:00:00 JST 2022
    12 aaa bbb cc:cc:cc:cc ddd
    34 eee fff gg:gg:gg:gg hhh
    
    Tue Nov 11 00:00:05 JST 2022
    78 iii jjj kk:kk:kk:kk lll
    99 mmm nnn oo:oo:oo:oo ppp
    
    Tue Nov 11 00:00:10 JST 2022
    12 qqq rrr ss:ss:ss:ss ttt
    34 uuu vvv ww:ww:ww:ww zzz
    
[/code]

w_file.csv↓

[code]

    Tue,Nov,11,00:00:00,12,aaa,bbb,cc:cc:cc:cc,ddd
    Tue,Nov,11,00:00:00,34,eee,fff,gg:gg:gg:gg,hhh
    Tue,Nov,11,00:00:05,78,iii,jjj,kk:kk:kk:kk,lll
    Tue,Nov,11,00:00:05,99,mmm,nnn,oo:oo:oo:oo,ppp
    Tue,Nov,11,00:00:10,12,qqq,rrr,ss:ss:ss:ss,ttt
    Tue,Nov,11,00:00:10,34,uuu,vvv,ww:ww:ww:ww,zzz
    
[/code]

[code]

    # test.py
    
    import csv
    
    read_file = "r_file.txt"
    write_file = "w_file.csv"
    
    
    with open(write_file, "w", encoding="utf_8", newline="") as w:
        writer = csv.writer(w)
        
        with open(read_file, "r", encoding="utf_8") as f:
            line = f.readline()
            
            while line:
                if line.startswith("Tue"):
                    
                    # JST 2022を除去
                    data = line.split()[:4]
                
                # 列の開始が数字か確認
                if line[0] >= '0' and line[0] <= '9':
                    elem = line.split()
                    
                    # 年月と時間を一番左に追記するため以下の処理を実施
                    csv_data = data + elem
                    
                    writer.writerow(csv_data)
                    
                line = f.readline()
    
[/code]


CC BY-SA 4.0
2022-12-13T13:09:09.947
92750
2022-12-15T23:33:52.137
2022-12-13T16:13:04.890
3060
question
python python3
python CSVファイル作成コード　チェックのお願い


曜日のアルファベット固定するのはどうかと思うので, 数字か改行かの判断で

[code]

    import csv
    import string
    import io
    
    text = '''
    Tue Nov 11 00:00:00 JST 2022
    12 aaa bbb cc:cc:cc:cc ddd
    34 eee fff gg:gg:gg:gg hhh
    
    Tue Nov 11 00:00:05 JST 2022
    78 iii jjj kk:kk:kk:kk lll
    99 mmm nnn oo:oo:oo:oo ppp
    
    Tue Nov 11 00:00:10 JST 2022
    12 qqq rrr ss:ss:ss:ss ttt
    34 uuu vvv ww:ww:ww:ww zzz
    '''
    
    def func(fp):
        for ln in fp:
            if ln[0] in string.digits:
                yield data +ln.split()
            elif ln[0] != '\n':
                data = ln.split()[:4]
    
    #with io.StringIO(text) as fp, open('some.csv', 'w', newline='') as csvfile:
    with (io.StringIO(text) as fp,
          io.StringIO() as csvfile):
        writer = csv.writer(csvfile)
        writer.writerows(func(fp))
    
        res = csvfile.getvalue()
    print(res)
    # Tue,Nov,11,00:00:00,12,aaa,bbb,cc:cc:cc:cc,ddd
    # Tue,Nov,11,00:00:00,34,eee,fff,gg:gg:gg:gg,hhh
    # Tue,Nov,11,00:00:05,78,iii,jjj,kk:kk:kk:kk,lll
    # Tue,Nov,11,00:00:05,99,mmm,nnn,oo:oo:oo:oo,ppp
    # Tue,Nov,11,00:00:10,12,qqq,rrr,ss:ss:ss:ss,ttt
    # Tue,Nov,11,00:00:10,34,uuu,vvv,ww:ww:ww:ww,zzz
    
[/code]

#### 追記 `func()`

`def func(fp)` について (コメントより)

以下のようにすると, `rows`を得ることができ  
関数内で listを準備し returnで返しても, ほぼ同じような処理内容になります

[code]

    with (io.StringIO(text) as fp,
          io.StringIO() as csvfile):
        rows = list(func(fp))
        writer = csv.writer(csvfile)
        writer.writerows(rows)
    
    #   writer.writerows([func(fp)])   # ⇐ 結果的に rows用意するのと同じ
    
[/code]

この場合 先の `func()` では以下の違いがあります

  * `rows`を用意しないことで記憶域を無駄にしない。例えば, 蓄えると主記憶を圧迫するような大量のデータであっても逐次処理可能
  * `yield` 見慣れてる人にとっては分かりやすい (かも)


CC BY-SA 4.0
2022-12-13T14:25:05.357
92755
2022-12-14T06:15:59.533
2022-12-14T06:15:59.533
43025
43025
92750
answer


空行で分割。

[code]

    import csv
    from itertools import takewhile
    
    read_file = 'r_file.txt'
    write_file = 'w_file.csv'
    
    with open(read_file, 'r', encoding='utf_8') as f, \
         open(write_file, 'w', encoding='utf_8', newline='') as w:
        writer = csv.writer(w)
        while (line := [*takewhile(lambda l: l[0]!='\n', f)]):
            prefix = line[0].split()[:4]
            output = [prefix + l.split() for l in line[1:] if '0' <= l[0] <= '9']
            if output: writer.writerows(output)
    
[/code]


CC BY-SA 4.0
2022-12-14T00:58:45.993
92761
2022-12-14T17:44:25.533
2022-12-14T17:44:25.533
47127
47127
92750
answer


将来このソースコードを基に仕様変更したり新しく類似のものを作るのであれば，例えば1ヶ月後の自分にとって内容を理解し易くしておくこと（可読性の向上）は改善と言えます。  
そこで，1ヶ月後に私が読むと想定してコードを拝見すると，「読み込み -> 加工 ->
書き込み」と処理を分けて記述しておきたくなります。なお，下記は入力ファイルが4行単位であることを前提にした記述例です。  
（追記）  
また，オリジナルとは異なり記述例では入力ファイルの大きさに比例してメモリ消費が増えます。

[code]

    import csv
    
    read_file = 'r_file.txt'
    write_file = 'w_file.csv'
    
    with open(read_file, 'r', encoding='utf-8') as f:
        data = [x.split() for x in f.read().splitlines()]
    
    rows = []
    for i in range(0, len(data), 4):
        time_info = data[i][:4]
        rows.append(time_info + data[i+1])
        rows.append(time_info + data[i+2])
    
    with open(write_file, 'w', encoding='utf-8') as f:
        csv.writer(f, lineterminator='\n').writerows(rows)
    
[/code]


CC BY-SA 4.0
2022-12-14T11:07:22.837
92785
2022-12-15T23:33:52.137
2022-12-15T23:33:52.137
54588
54588
92750
answer