2013-05-16 6 views
1

두 파일에서 (네트워크 로그온 사용자 이름은 무엇입니까?) 일치 시키려고합니다. All은 내가 관심이있는 (또는 앞으로있을 예정인) 이름의 텍스트 파일입니다. 현재,이 같은 일을 해요 : 파이썬두 파일의 데이터 일치

def find_files(directory, pattern): 
    #directory= (raw_input("Enter a directory to search for Userlists: ") 
    directory=("c:\\TEST") 
    os.chdir(directory) 
    for root, dirs, files in os.walk(directory): 
     for basename in files: 
      if fnmatch.fnmatch(basename, pattern): 
       filename = os.path.join(root, basename) 
       yield filename 


for filename in find_files('a-zA-Z0-9', '*.txt'): 
    with open (filename, "r") as file1: 
     with open ("c:/All.txt", "r") as file2: 
      list1 = file1.readlines()[18:] 
      list2 = file2.readlines() 
      for i in list1: 
       for j in list2: 
        if i == j: 

I'n 새를이 최선이며,이 일을 가장 효율적인 방법 궁금하고있다. 나에게는 초보자로서 조금 어수선하지만, 현재의 코딩 지식은 내가 지금 생각할 수있는 최선이다. 도움과 조언을 주시면 감사하겠습니다.

답변

4

하나의 파일을 먼저 읽고 세트에 저장하고 싶습니다. 집합의 멤버쉽 테스트는 매우 효율적입니다. 많이 첫 번째 파일의 모든 줄에 대해 두 번째 파일의 줄을 반복하는 것보다 더 많은 테스트가 필요합니다.

그러면 두 번째 파일을 읽고 행 단위로 처리하고 행이 일치하는지 테스트해야합니다.

메모리에 보관하는 파일은 All.txt의 크기에 따라 다릅니다. < 1000 라인 정도라면 메모리에 저장하고 다른 파일과 비교하십시오. All.txt이 실제로 큰 경우 처리 할 모든 file1에 대해 다시 열고 file1의 첫 번째 18 줄만을 메모리에 읽어서 All.txt에있는 모든 줄에 대해 한 줄씩 일치시킵니다.

파일의 18 줄만 읽으려면 itertools.islice()을 사용하십시오. 파일은 iterables이며 islice()은 읽을 줄의 하위 집합을 선택하는 가장 쉬운 방법입니다.

1 메모리에 All.txt 읽기 : All.txt이 큰

from itertools import islice 

with open ("c:/All.txt", "r") as all: 
    # storing lines without whitespace to make matching a little more robust 
    all_lines = set(line.strip() for line in all) 

for filename in find_files('a-zA-Z0-9', '*.txt'): 
    with open(filename, "r") as file1: 
     for line in islice(file1, 18): 
      if line.strip() in all_lines: 
       # matched line 

경우, 재 열기 All.txt을 그리고, 제 세트의 각 파일들 (18 개) 행을 저장 한 라인 씩 진행하여 :

for filename in find_files('a-zA-Z0-9', '*.txt'): 
    with open(filename, "r") as file1: 
     file1_lines = set(line.strip() for line in islice(file1, 18)) 
    with open ("c:/All.txt", "r") as all: 
     for line in all: 
      if line.strip() in file1_lines: 
       # matched line 

이 아니고이 아닌 디렉토리는 find_files()으로 변경해야합니다. os.walk()에 이미 디렉토리 이름이 전달되었습니다. fnmatch 모듈은 또한 .filter() 방법을 가지고 사용하는 루프 대신 개별적으로 각 파일에 fnmatch.fnmatch()를 사용 files 이상 : Martijin, 일부 우수한 도움의

def find_files(directory, pattern): 
    directory = "c:\\TEST" 
    for root, dirs, files in os.walk(directory): 
     for basename in fnmatch.filter(files, pattern): 
      yield os.path.join(root, basename) 
+0

. 대단히 감사합니다 – user2377057