0

そのため、「クラスター」という単語の下の行数に基づいて解析しようとしている、均一にフォーマットされたテキストファイルがあります。これまでの私のコードは次のとおりです。

f = open('file.txt', 'r')
main_output = open('mainoutput.txt', 'w')
minor_output = open('minoroutput.txt', 'w')
f_lines = f.readlines()
main_list = []
minor_list = []
for n, line in enumerate(open('file.txt')):
    if 'cluster' in line:
        if 'cluster' in f_lines[n+1] or f_lines[n+2] or f_lines[n+3]:
            minor_list.append(line)
            minor_list.append(f_lines[n+1])
            minor_list.append(f_lines[n+2])
            minor_list.append(f_lines[n+3])
        if 'cluster' not in f_lines[n+1] or f_lines[n+2] or f_lines[n+3]:
            main_list.append(line)
            main_list.append(f_lines[n+1])
            main_list.append(f_lines[n+2])
            main_list.append(f_lines[n+3])
minor_output.write(''.join(minor_list))
main_output.write(''.join(main_list))
f.close()
main_output.close()
minor_output.close()

テキストファイルの形式は次のとおりです。

>Cluster 1
line 1
line 2
line 3
...

>Cluster 2
line 1
line 2
...

and so on for many clusters.

各クラスターの下には、1から100+までの可変数の行があります。これらのクラスターを各クラスターの行数(アイテム)で並べ替えることに興味があります。このコードは機能していますが、2つの出力ファイルは同じです。私のコードや戦略に関する助けは素晴らしいでしょう!

4

1 に答える 1

1

あなたが正しく投稿したコードを理解している場合は、クラスター内のアイテムの数に応じて、データを2つの異なるファイルに分類する必要があります。3つ以下の場合、クラスターはになりminoroutput.txt、それより多い場合は、になりmainoutput.txtます。

コードがデータを適切に並べ替えない原因になっていると思われる重大な論理エラーがいくつかあります。

まず、行に単語が含まれているかどうかを確認するためのテストは、サンプルデータのように"cluster"大文字と一致しません。"Cluster"これは、表示したサンプルデータの問題である可能性があり、lower()確認する前に回線を呼び出すことで簡単に修正できます。

次に、後の行のチェックが正しくありません。コードif 'cluster' in f_lines[n+1] or f_lines[n+2] or f_lines[n+3]は3つの文字列のそれぞれをチェックするの"cluster"ではなく、最初の文字列のみをチェックします。2番目と3番目の文字列は、ブール値のコンテキストですべて単独で評価されています。空の行でない場合は空の行になりTrue、ほとんどの場合、式全体も真になります。これが機能するためには、チェックする必要があり'cluster' in f_lines[n+1] or 'cluster' in f_lines[n+2] or 'cluster' in f_lines[n+3]ます(ただし、後でより良い代替案を示します)。同じ問題が他のステートメントでも発生します。この場合、とはおそらく両方とも空ではないためif、ほとんどの場合True、条件から結果が得られます。f_lines[n+2]f_lines[n+3]

最後に、クラスターを書き出すためのロジックはおそらく正しくありません。多くのクラスターにはそれよりも多いまたは少ない項目がありますが、現在は常に正確に4行が書き出されます。に書き込まれるすべてのクラスターについてmainoutput.txt、一部の行が破棄されます(これは意図的なものである可能性があります)。ただし、に書き込まれる一部のクラスターminoroutupt.txtでは、1つまたは2つの項目しかないクラスターの後に、次のクラスターの開始を書き出すという明らかなバグが発生します。

これが私があなたのために働くと思ういくつかのコードです。ループを変更して、行をリストに1回、2回目にを読み取るのではなく、ファイルを1回だけ読み取るようにしましたenumerate。次の3行を明示的に確認するのではなく、各行をリストに追加し、行が含まれるたびclusterに(大文字と小文字を区別して)リセットします。

with open('file.txt', 'r') as f, \
     open('mainoutput.txt', 'w') as main_out, \
     open('minoroutput.txt', 'w') as minor_out:
    cluster = [] # this variable will hold all the lines of the current cluster
    for line in f:
        if 'cluster' in line.lower(): # if we're at the start of a cluster
            if len(cluster) > 4: # long clusters go in the "main" file
                main_out.writelines(cluster) # write out the lines
                # main_out.writelines(cluster[:4])
            else:
                minor_out.writelines(cluster) # or to the other file

            cluster = [] # reset the cluster variable to a new, empty list

        cluster.append(line) # always add the current line to cluster

    if len(cluster) > 4: # repeat the writing logic for the last cluster
        main_out.writelines(cluster)
        # main_out.writelines(cluster[:4])
    else:
        minor_out.writelines(cluster)

クラスタ内の最初の3つのアイテムのみを出力する(残りは破棄する)writelines場合は、コメントのない行の直前にあるコメント付きの2行を使用します。mainout.txtのすべての行を印刷する代わりの合理的な方法はないと思いますminorout.txt

file.txtこれらの内容で与えられる:

>Cluster 1
line 1
line 2
line 3
>Cluster 2
line 1
line 2
line 3
line 4
>Cluster 3
line 1
>Cluster 4
line 1
line 2
line 3
line 4
line 5

上記のコードは2つのファイルを出力します:

mainoutput.txt

>Cluster 2
line 1
line 2
line 3
line 4
>Cluster 4
line 1
line 2
line 3
line 4
line 5

minoroutput.txt

>Cluster 1
line 1
line 2
line 3
>Cluster 3
line 1
于 2013-02-10T23:12:25.087 に答える