중요한 점은 목록 이해가 새로운 목록을 생성한다는 것입니다. 생성기는 비트를 소비 할 때 소스 자료를 "필터링"하는 반복 가능한 객체를 생성합니다.
"hugefile.txt"라는 2TB 로그 파일이 있고 "ENTRY"라는 단어로 시작하는 모든 행의 내용과 길이를 원한다고 가정하십시오.
따라서 목록 이해력을 작성하여 시작해보십시오.
logfile = open("hugefile.txt","r")
entry_lines = [(line,len(line)) for line in logfile if line.startswith("ENTRY")]
이렇게하면 전체 파일을 정리하고 각 줄을 처리하며 일치하는 줄을 배열에 저장합니다. 따라서이 어레이에는 최대 2TB의 컨텐츠가 포함될 수 있습니다. 그것은 많은 RAM이며 아마도 귀하의 목적에 실용적이지 않을 것입니다.
대신 생성기를 사용하여 콘텐츠에 "필터"를 적용 할 수 있습니다. 결과를 반복하기 시작할 때까지 실제로 데이터를 읽지 않습니다.
logfile = open("hugefile.txt","r")
entry_lines = ((line,len(line)) for line in logfile if line.startswith("ENTRY"))
아직 파일에서 한 줄도 읽지 않았습니다. 실제로 결과를 더 필터링하고 싶다고 가정 해보십시오.
long_entries = ((line,length) for (line,length) in entry_lines if length > 80)
아직 읽은 것은 없지만 지금 우리가 원하는대로 데이터에 작용할 두 개의 생성기를 지정했습니다.
필터링 된 줄을 다른 파일에 쓸 수 있습니다.
outfile = open("filtered.txt","a")
for entry,length in long_entries:
outfile.write(entry)
이제 입력 파일을 읽습니다. for
루프가 계속해서 추가 라인을 요청 함에 따라 long_entries
생성기 는 생성기에서 라인을 요구 entry_lines
하며 길이가 80자를 초과하는 라인 만 반환합니다. 그리고 entry_lines
생성기는 logfile
반복자에게 행을 요청하고 (표시된대로 필터링 됨) 파일을 읽습니다.
따라서 완전히 채워진 목록의 형태로 출력 함수에 데이터를 "푸시"하는 대신 출력 함수에 필요할 때만 데이터를 "풀"하는 방법을 제공합니다. 이것은 우리의 경우 훨씬 더 효율적이지만 융통성이 없습니다. 제너레이터는 일방 통행입니다. 읽은 로그 파일의 데이터는 즉시 버려 지므로 이전 줄로 돌아갈 수 없습니다. 반면에 데이터가 완료된 후에는 데이터를 보관하는 것에 대해 걱정할 필요가 없습니다.
[exp for x in iter]
그냥 설탕이 될 수list((exp for x in iter))
있습니까? 또는 실행 차이가 있습니까?