2014-11-22 2 views
0

이 코드를 어떻게 최적화 할 수 있습니까? 파일에서 중복 된 선을 제거하고 싶지만 비효율적 인 경우 집합을 사용한다고 생각하고 파싱 할 수있는 파일의 크기를 제한합니다. 임시 파일에대용량 파일에서 중복 줄 제거 최적화

file = open("sample.txt") 

output = [] 
alreadyseen = set()  

while True: 
    lines = file.readlines(100000) 
    if not lines: 
     break 
    for line in lines: 
     pass # do something 
     if line not in alreadyseen: 
      output.append(line) 
      alreadyseen.add(line) 
    print(output) 
+0

파일이 얼마나 큰 : 두 가지 접근 방식을 결합

는 다음과 같이 보이는? 이진 검색 트리 (Log N 조회를 제공합니다)는 어떻습니까? 또는 줄을 정렬하면 이전 줄만 반복하고 기억할 수 있습니다 ...? – erewok

+1

메모리에 모두 맞을 경우 여기에있는 기술이 아마도 최적 일 것입니다. 적합하지 않더라도 작동하는 방법에 관심이 있다면 그렇게 말하십시오. –

+0

루프 밖에서'print (output) '을 사용하지 않겠습니까? – Eric

답변

1

귀하의 알고리즘은 가장 빠른 방법이 될 것입니다 이것을하기 위해서, 그러나 당신이 지적했듯이 그것은 당신이 기억에 들어갈 수있는 라인의 수에 의해 제한 될 것입니다. 이 문제를 완화하고 더 큰 파일을 처리 할 수있는 몇 가지 기술이 있습니다.

첫 번째는 한 번에 한 줄만 읽고 쓰는 것입니다. 개별적으로 처리하기 때문에 한 번에 100,000 개의 청크를 읽을 필요가 없으며 모든 고유 한 결과를 단일 문자열로 유지할 이유가 없습니다. 폐기물을 최소화하기 위해 한 번에 한 줄씩 읽고 쓰십시오.

두 번째는 더 긴 문자열에 대해 암호화 해시를 대체하는 것입니다. 해시는 라인 자체가 얼마나 긴지에 관계없이 고정 된 크기입니다. 동일한 해시를 생성하는 두 개의 문자열 가능성에 대해 걱정할 경우 해시가 충분히 크면 동일한 해시를 생성하는 두 개의 문자열 확률이 두 개의 다른 문자열을 허용하는 RAM 결함 확률보다 낮습니다. 동등한 비교, 심지어는 birthday paradox을 고려하십시오.

import hashlib 

sha256 = hashlib.sha256() 
alreadyseen = set() 
with open("sample.txt") as file: 
    for line in file: 
     pass # do something 
     key = line if len(line) < 32 else sha256(line) 
     if key not in alreadyseen: 
      alreadyseen.add(key) 
      print(line) 
1

쓰기는 단지 두 파일을 다시 열고 file2의 내용으로 file1를 업데이트 목록에있는 모든 라인을 저장 피하기 위해 :

alreadyseen = set() 
with open(file_1) as f1, open(file_2, "w") as f2: 
    while True: 
     lines = f1.readlines(100000) 
     if not lines: 
      break 
     for line in lines: 
      pass # do something 
      if line not in alreadyseen: 
       f2.write(line) 
       alreadyseen.add(line) 

with open(file1, "w") as f1, open(file_2) as f2: 
    for line in f2: 
     f1.write(line)