1

オンラインで答えを探してみましたが、残念ながら成功しませんでした。したがって、私はここで尋ねています:

file1のすべての行が に存在するかどうかを調べようとしていfile2ます。幸いなことに、個々の単語などではなく、行全体を比較することができます。不運にも、私は GB ファイルを扱っているので、試した基本的な解決策のいくつかでメモリ エラーが発生しました。

現時点では、動作しない次のコードがあります。いくつかのガイダンスをいただければ幸いです。

# Checks if all lines in file1 are present in file2
def isFile1SubsetOfFile2(file1 , file2):
    file1 = open(file1, "r")


    for line1 in file1:        
        with open(file2, "r+b") as f:

            mm=mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) 
            my_str_as_bytes = str.encode(line1)
            result = mm.find(line1.strip().encode())
            print(result)
            if result == -1:
                return False
    return True

サンプルファイル 2:

This is line1.
This is line2.
This is line3.
This is line4.
This is line5.
This is line6.
This is line7.
This is line8.
This is line9.

たとえば、file1が次の場合に合格する必要があります。

This is line4.
This is line5.

たとえば file1 が次の場合、失敗するはずです。

This is line4.
This is line10.

編集:他の人の利益のために、コードの作業バージョンを追加しました。メモリエラーはありませんが、非常に遅いです。

4

2 に答える 2

0

うまくいかない理由はわかりませんが、解決方法を知っていると思います:

def is_subset_of(file1, file2):
    with open(file1, 'r') as f1, open(file2, 'r') as f2:
        for line in f1:
            line = line.strip()
            f2.seek(0)   # go to the start of f2
            if line not in (line2.strip() for line2 in f2):
                return False
    return True

これにより、2 番目のファイルが複数回開かれるのを回避できます。これは、行ごとに常に最初から検索し直し、いつでもメモリ内に 2 行しか保持できないためです。それは非常にメモリに優しいはずです。

file1別の方法 (より高速になる可能性があります) は、 と の両方をソートすることfile2です。そうすれば、行ごとに比較して、文字列が最初のファイルの文字列より字句的に小さい場合、他のファイルの次の行に移動できます。その代わりに でO(n**2)実行できますO(n*log(n))。ただし、それははるかに複雑であり、GB のファイルを並べ替えることが理にかなっているのかどうかはわかりません (メモリを使いすぎる可能性があります!)。

于 2017-08-25T16:48:39.450 に答える