python : 파일에 중복이 있는 경우, 정렬 유지하고 삭제하기.

구글에서, ‘Python remove duplicates’ 로 검색하면, 몇몇 글들을 찾을 수 있는데, 대부분 동일한 소스코드를 공유하고 있었다.

lines_seen = set() # holds lines already seen
outfile = open("out.txt", "w")
for line in open("input.txt", "r"):
    if line not in lines_seen: # not a duplicate
        outfile.write(line)
        lines_seen.add(line)
outfile.close()

이것과 동일한 코드가 Python Cookbook(O’REILLY) 에도 기재돼 있다.

저걸 쓰면, 정렬 순서는 그대로 유지하면서 중복된 줄만 지워준다. 먼저 나온 게 살아있고, 나중 나온 건 삭제된다.

그런데, 여기엔 작은(?) 문제가 몇개 있다.

  • 일부러 넣어놓은 빈 줄이 모두 삭제된다. (맨 첫 빈 줄은 남아있겠지만)
  • 빈칸 외에, # 만 넣어 놓은 행도 있었는데 역시 삭제된다.
  • 중복이 있든, 없든, 새로운 파일은 무조건 만들어진다.

의도한 공백은 다음과 같이 해결가능하다.

lines_seen = set() # holds lines already seen
outfile = open("out.txt", "w")
for line in open("input.txt", "r"):
    if line.startswith(('#', '\n')) : # 빈칸/# 로 시작하지 않는 행은 그냥 넘김. (중복 허용)
        outfile.write(line)
        continue
    if line not in lines_seen: # not a duplicate
        outfile.write(line)
        lines_seen.add(line)
outfile.close()

다만, 무조건 out.txt 가 만들어지는 문제는 여전하다.

이 문제를 해결하기 위해선 동일한 for 를 두번 사용해야 하는데..
(중복이 있는지 확인하기 위한 for, 파일 출력을 위한 for)
그거 말고 뭔가 번뜩이는 방법은 없으려나??

아니면, for 에서 바로 출력을 하지 말고, 리스트등으로 만들어 놓은 뒤, 중복이 발견되면 마지막에 그 리스트를 파일로 출력하게끔 하는 방법도 있을 수 있겠다.

Tags:

안녕하세요. 글 남겨주셔서 고맙습니다.