2011-02-16 5 views
2

에서 작동하지 않는 나는 다음과 같은 코드가 있습니다파이썬 : itertools.islice 루프

#opened file f 
goto_line = num_lines #Total number of lines 
while not found: 
    line_str = next(itertools.islice(f, goto_line - 1, goto_line)) 
    goto_line = goto_line/2 
    #checks for data, sets found to True if needed 

line_str는 첫 번째 패스 정확하지만 그 이후로 모든 패스는해야 다음 다른 라인을 읽고 있습니다.

예를 들어, goto_line은 1000으로 시작합니다. 그런 다음 다음 루프 인 goto_line은 500이지만 500 행은 읽지 않습니다. 1000 행에 더 가까운 행을 읽습니다.

큰 파일에서 특정 행을 읽는 것이 필요 이상으로 읽지 않으려 고합니다. 때로는 선으로 뒤로 점프하고 때로는 앞으로 건너 뛰기도합니다.

나는 linecache를 시도했지만 일반적으로 같은 파일에서이 코드를 두 번 이상 실행하지 않습니다.

+0

어떤 줄을 읽으며 어떤 줄을 읽으려고합니까? (또한 : 더 깊게 들여 씁니다 .- 예를 들어, 4 칸 - 이렇게 읽는 것이 어렵습니다.) – delnan

+0

제가 사용하는 것에 대해서는 4382898 줄을 읽으라고 말하고 첫 번째 통과에서 올바르게합니다. 그런 다음 goto_line이 2191449로 바뀌지 만, islice는 6574286 행으로 돌아갑니다. – Zeno

답변

5

파이썬 반복자는 한 번만 사용할 수 있습니다. 이것은 예제에서 가장 쉽게 볼 수 있습니다. 다음 코드

from itertools import islice 
a = range(10) 
i = iter(a) 
print list(islice(i, 1, 3)) 
print list(islice(i, 1, 3)) 
print list(islice(i, 1, 3)) 
print list(islice(i, 1, 3)) 

인쇄

[1, 2] 
[4, 5] 
[7, 8] 
[] 

슬라이싱은 항상 우리가 지난 시간을 중지했던 시작합니다.

코드 작업을 수행하는 가장 쉬운 방법은 f.readlines()을 사용하여 파일의 행 목록을 얻은 다음 일반 파이썬 목록 슬라이스 [i:j]을 사용하는 것입니다. islice()을 사용하려면 매번 f.seek(0)을 사용하여 처음부터 파일을 읽을 수 있지만 매우 비효율적입니다.

+0

필자는 필요한 것 이상을 읽고 싶지 않습니다. 매우 큰 파일입니다. 우아하지 않고 여기에서 효율적 이길 바란다. – Zeno

+2

@Zeno : 줄의 길이가 다르기 때문에 선행하는 모든 줄을 읽지 않고 줄 번호로 텍스트 파일에서 줄을 찾는 것은 불가능합니다. –

+0

"파이썬 반복자는 한 번만 사용할 수 있습니다."제 질문에 감사합니다. 감사합니다. – Zeno

0

(이 방법은 아마도 파일을 여는 방법에 따라 약간의 방법이 있습니다.) 파일로 돌아갈 수는 없습니다. 표준 파일 반복자 (실제로 대부분의 반복자 - 파이썬의 반복자 프로토콜은 순방향 반복자 만 지원합니다) 앞으로 이동합니다. 따라서 k 행을 읽은 후 다른 k/2 행을 읽으면 실제로 k+k/2 번째 행이 표시됩니다.

전체 파일을 메모리로 읽으려고 시도하지만 많은 양의 데이터가 있으므로 메모리 소비가 적절하게 문제가됩니다. file.seek을 사용하여 파일을 스크롤 할 수 있습니다. 하지만 여전히 많은 작업이 있습니다. 아마도 memory-mapped file을 사용할 수 있을까요? 선이 고정 크기 인 경우에만 가능합니다. 필요한 경우 라인 수를 사전 계산하여 모든 회선을 저장하면됩니다 (잘못 입력하지 않은 경우 약 int(log_2(line_count)) + 1). 반복하지 않아도됩니다. 전체 파일을 읽은 후에 다시 스크롤하십시오.

+0

그래, 거대한 파일이야. 왜 내가 islice를 사용하고 있고, readlines이 아닌지. – Zeno

+0

mmap은 아마도 32 비트 OS이기 때문에 아마 작동하지 않을 것이고 그래서 처음 4GB 만 읽을 수 있습니다. – Zeno

+0

@Zeno : 그리고 마지막으로 제안 된 솔루션 (한 번 반복하고 필요한 모든 행을 저장하는 방법)은 어떨까요? – delnan

관련 문제