2013-10-28 3 views
0

파일을 열고 "myfile"이라고 이름을 지정했습니다. 두 개의 다른 사전을 만들고 싶지만 파일이 나와 닫히고 첫 번째 사전에 첫 번째 사전을 만들었 기 때문에 가정합니다. 히스토그램에 대한 빈 사전을 얻었으므로 myfile을 x로 사용하고 두 번째 루프에 대해 f 대신 x를 사용하여이 "ValueError : 닫힌 파일에 대한 I/O 작업"을 얻었습니다.파일에서 두 개의 사전을 만드는 동안 파일을 열어두기

또한, 차이가 나는 경우 클래스의 함수에서이 작업을 수행하고 있습니다.

누구나이 작업을 수행하는 방법을 알고 있습니까?

d = {} 
    d2 ={} 
    with myfile as f: 
     next(f) 
     for line in f: 
      k, v = line.split() 
      d[int(k)] = int(v) 
      next(f) 

     for line in f: 
      items = line.split() 
      key, values = int(items[0]), items[1:] 
      d2.setdefault(key, []).extend(values) 


    hist = defaultdict(list) 
    for key, values in d2.iteritems(): 
     hist[len(values)].append(key) 
    histogram = dict(hist) 
+0

왜 두 개의 루프가 필요합니까? 한번'f'를 반복 할 수 없습니까? – ForeverWintr

+0

seek()을 사용하여 파일의 처음으로 현재 위치를 다시 설정할 수 있습니다. –

답변

4

반복기를 처음으로 반복하면됩니다. 따라서 다시 루프하려고 할 때 볼만한 것이 없습니다.

모든 논리를 동일한 루프에 넣기 만하면됩니다. 나는 당신의 루프가 무엇을하고 있는지 잘 모르겠지만, 첫번째 루프처럼 보이는 것은 홀수 번호의 모든 (0- 인덱스 된) 라인에만 적용해야한다. 이것은 enumerate으로 쉽게 완성된다. 두 번째 루프는 모든 라인에 적용되는 것처럼 보입니다. 따라서이 루프로 시작하여 "첫 번째"루프의 기능을 추가하십시오. 이 같은 :

with myfile as f: # Better: with open('/some/file.txt', 'rb') as f: 
    for i, line in enumerate(f): 
     # "Second" loop 
     items = line.split() 
     key, values = int(items[0]), items[1:] 
     d2.setdefault(key, []).extend(values) 

     # "First" loop 
     if i % 2 != 0: # Only process odd-numbered lines 
      k, v = items 
      d[int(k)] = int(v) 
+0

my 루프 사이에 myfile.seek (0)을 추가했습니다. 답변을 추가하고 싶지만 충분한 평판이 없으므로 사용할 수 없습니다. – user2926009

+0

@ user2926009 파일이 너무 크거나 실행 횟수가 많으면 코드를 단일 루프로 리팩터링하여 더 빨리 실행하기를 원할 수도 있습니다. –

2

당신 만 한 번 심각하게해야 할 데이터에 대한 루프 헨리 - keiter의 추천 @ 첫 번째 루프 그러나

, 후 f.seek(0) 전화를 묻는 질문을 해결합니다.

1

헨리와 동의합니다 : 실제로 두 패스 알고리즘을 수행 할 필요가 없다면 seek()을 수행하지 마십시오.

할 수없는 이유가 있습니까?

또한 첫 번째 루프에서 next(f)을 사용하면 의심스러운 것처럼 보입니다. 일반적으로 반복을 통해 반복하는 경우 반복을 지원하는 다른 작업을 수행하고 싶지 않습니다.

나는 다음과 같이 뭔가를 기다리고 있었다 : 파일을 통해 단일 패스를 반복 할 수

with myfile as f: ## FIXME: this is suspect. 'myfile' is accessible outside this 
        ## `with` already, so there's something weird here. 
    for (index, line) in itertools.izip(itertools.count(), f): 
     if index % 2 == 1: 
      k, v = line.split() 
      d[int(k)] = int(v) 

     items = line.split() 
     key, values = int(items[0]), items[1:] 
     d2.setdefault(key, []).extend(values) 

. 원래 코드의 첫 번째 루프는 파일의 홀수 라인 만 신경 써야하므로이 재 작성을 통해 해당 아이디어가 표현됩니다.


여기서는 with의 사용이 보입니다. 작성된

with open(...) as f: 
    ... 

그러나 코드 이미 열이 : 우리는 일반적으로 우리가 자원의 개폐를 통해 책임을 져야하고, with의 몸 안에 이름을 지정하기 위해 with를 원한다면 그렇게 그것. 즉, 여기에 myfile 변수가 초기화되었으며이 변수는 with 외부에서 계속 액세스 할 수 있습니다.

우리는이 같은 try/ finally, 사용 된 경우 우리는 코드에 더 많은 정의를 할 것

: 코드 myfile 보장 될 것이라고 명확하게

try: 
    ... ## use myfile here instead of f 
finally: 
    myfile.close() 

try/finally의 말에 폐쇄를 .

관련 문제