For 루프 및 Tell 함수를 사용하여 각 라인의 시작 위치 목록을 채우는 방법은 무엇입니까?

user2316667

내가하고 싶은 것은 각 줄의 시작 위치 목록을 만들어서 정말 빠르게 찾을 수 있도록하는 것입니다. "next () '호출에 의해 위치 지정이 비활성화되었습니다."라는 오류가 발생합니다. 이것을 어떻게 극복합니까?

>>> in_file = open("data_10000.txt")
>>> in_file.tell()
0
>>> line_numbers = [in_file.tell() for line in in_file]
Traceback (most recent call last):
  File "<pyshell#9>", line 1, in <module>
    line_numbers = [in_file.tell() for line in in_file]
  File "<pyshell#9>", line 1, in <listcomp>
    line_numbers = [in_file.tell() for line in in_file]
OSError: telling position disabled by next() call

참고 :이 컨텍스트에서 색인은 행 번호를 탐색 위치와 관련시킵니다.

SzieberthAdam

간단한 생성기로 문제를 해결할 수 있습니다.

def line_ind(fileobj):
    i = 0
    for line in fileobj:
        yield i
        i += len(line)

라인 시작 위치의 인덱스를 하나씩 생성 (생성)합니다. 일반 함수는 값을 반환하고 중지합니다. 발전기가 값을 산출하면 소진 될 때까지 계속 실행됩니다. 내가 여기서 한 것은 0을 산출 한 다음 첫 번째 줄의 길이를 추가 한 다음 두 번째 줄의 길이를 추가하는 것입니다. 그러면 원하는 인덱스가 생성됩니다.

산출 된 값을 목록에 넣으려면 사용할 수 list(generator())있는 것과 동일하게 사용할 수 있습니다 list(range(10)). 파일을 열 때 with아래와 같이 사용하는 것이 좋습니다 . 파일 개체를 자주 닫는 것을 잊기 때문이 아니라 예외가 발생하면 자동으로 닫습니다. 따라서 아래 코드에는 두 개의 시작 위치 인덱스 목록이 있습니다.

with open("test.dat", encoding="utf-8") as f:
    u_ind = list(line_ind(f))
    f.seek(0)
    u = f.read()

with open("test.dat", "rb") as f:
    b_ind = list(line_ind(f))
    f.seek(0)
    b = f.read()

유니 코드 문자열의 인덱스는 바이트 문자열과 다를 수 있습니다. 예를 들어 악센트 부호가있는 문자는 2 바이트의 공간을 차지할 수 있습니다. 첫 번째 목록에는 유니 코드 문자의 색인이 포함됩니다. 파일의 일반 문자열 표현을 다룰 때 이것을 사용합니다. 아래 예는 테스트 파일의 두 경우에서 색인 값이 어떻게 다른지 보여줍니다.

>>> u_ind[-10:]
[24283, 24291, 24300, 24309, 24322, 24331, 24341, 24349, 24359, 24368]
>>> b_ind[-10:]
[27297, 27306, 27316, 27326, 27342, 27352, 27363, 27372, 27383, 27393]

이제 마지막 줄의 내용을 원합니다.

>>> u[24368:]
'S-érték=9,59'
>>> b[27393:]
b'S-\xc3\xa9rt\xc3\xa9k=9,59'

그러나 seek()이전 에 사용하려는 경우 read()바이트 인덱스를 고수해야합니다.

>>> with open("test.dat", encoding="utf-8") as f:
...     f.seek(27393)
...     f.read()
...
27393
'S-érték=9,59'
>>> with open("test.dat", "rb") as f:
...     f.seek(27393)
...     f.read()
...
27393
b'S-\xc3\xa9rt\xc3\xa9k=9,59'

첫 번째 경우에 24368을 사용하는 것은 여기서 끔찍한 실수입니다.

주 당신이 때 read()문자열 / bytestring 객체 파일의 내용과 개별 라인을 처리 할 후에는 사용에 현명하다 .splitlines().

이것이 도움이 되었기를 바랍니다!

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

Related 관련 기사

뜨겁다태그

보관