1. ホーム
  2. python

[解決済み] Writelinesは改行なしで行を書き、ファイルを埋めるだけです。

2023-01-25 05:59:32

質問

ファイルにリストを書き出すプログラムを持っています。 リストはパイプで区切られた行のリストで、このようにファイルに書き込まれる必要があります。

123|GSV|Weather_Mean|hello|joe|43.45
122|GEV|temp_Mean|hello|joe|23.45
124|GSI|Weather_Mean|hello|Mike|47.45

しかし、それは彼らの行を書きました......このああ。

123|GSV|Weather_Mean|hello|joe|43.45122|GEV|temp_Mean|hello|joe|23.45124|GSI|Weather_Mean|hello|Mike|47.45

このプログラムは、すべての行を改行せずに1行に書きました。これはとても痛いし、これを元に戻す方法を考えなければならないのですが、とにかく、私のプログラムはどこで間違っているのでしょうか?私は、write linesは1行にすべてを書き込むのではなく、ファイルの下に行を書き込むものだと思っていました。

fr = open(sys.argv[1], 'r') # source file
fw = open(sys.argv[2]+"/masked_"+sys.argv[1], 'w') # Target Directory Location

for line in fr:
    line = line.strip()
    if line == "":
        continue
    columns = line.strip().split('|')
    if columns[0].find("@") > 1:
        looking_for = columns[0] # this is what we need to search
    else:
        looking_for = "[email protected]"
    if looking_for in d:
        # by default, iterating over a dictionary will return keys
            new_line = d[looking_for]+'|'+'|'.join(columns[1:])
            line_list.append(new_line)
    else:
        new_idx = str(len(d)+1)
        d[looking_for] = new_idx
        kv = open(sys.argv[3], 'a')
        kv.write(looking_for+" "+new_idx+'\n')
        kv.close()
        new_line = d[looking_for]+'|'+'|'.join(columns[1:])
        line_list.append(new_line)
fw.writelines(line_list)

どのように解決するのですか?

特に、標準ライブラリや人気のあるサードパーティライブラリでは、いくつかの読み込み関数は改行を除去しますが、ほとんどすべての書き込み関数( log -関連のものを除く) は改行を追加しないからです。

というようなことをするPythonのコードがたくさん出ているわけです。

fw.write('\n'.join(line_list) + '\n')

または

fw.write(line + '\n' for line in line_list)

どちらかが正しいです。もちろん、それをラップする独自のwritelinesWithNewlines関数を書くこともできます...。

しかし、これは避けられない場合にのみ行うべきでしょう。

Greg Hewgillの提案のように、最初の場所で改行を作成/維持できればよりよいでしょう。

line_list.append(new_line + "\n")

また、生のテキスト行よりも高いレベルで作業できれば、さらによいでしょう。たとえば csv モジュールを使うなどして、より高いレベルで作業できるとなお良いでしょう。

例えば fw を定義した直後に、次のようにします。

cw = csv.writer(fw, delimiter='|')

では、この代わりに

new_line = d[looking_for]+'|'+'|'.join(columns[1:])
line_list.append(new_line)

こうするんだ。

row_list.append(d[looking_for] + columns[1:])

そして最後には、この代わりに

fw.writelines(line_list)

こうするんだ。

cw.writerows(row_list)

最後に、あなたのデザインは "ファイルを開き、ファイルに追加する行のリストを構築し、それらをすべて一度に書き込む" です。ファイルを上に開くのであれば、行を 1 つずつ書けばよいのではないでしょうか。単純な書き込みを使うにせよ、あるいは csv.writer を使うにせよ、そうすればあなたの生活はよりシンプルになり、あなたのコードはより読みやすくなるでしょう。(時には、ファイルを一度に書くことが単純であったり、効率的であったり、正しい理由であったりすることがありますが、いったん open をプログラムの反対側に移動させたら、その時点で write の反対側まで書いてしまうと、all-at-onceの利点がほとんどなくなってしまいます)。