2016-07-20 3 views
0

파이썬에서 csv.reader을 사용하여 사전에 csv 파일을 읽습니다. CSV 파일 첫 번째 열은 날짜 오브젝트로서 판독하고 dict의 열쇠가된다 (2 개 가능한 포맷 중 하나)의 날짜이며, I는 칼럼 3 및 4 읽어csv.reader miss first line

import datetime as dt 
import csv 
with open(fileInput,'r') as inFile: 
    csv_in = csv.reader(inFile) 
    try: 
     dictData = {(dt.datetime.strptime(rows[0], '%d/%m/%Y %H:%M')): [rows[3], rows[4]] 
         for rows in csv_in} 
    except: 
     dictData = {(dt.datetime.strptime(rows[0], '%Y-%m-%d %H:%M:%S')): [rows[3], rows[4]] 
         for rows in csv_in} 

그것을 파일의 첫 번째 날짜 (1/7/2012 00:00)가 사전에 표시되지 않는 것을 제외하고는 작동합니다. csv.reader에게 첫 번째 행이 헤더 행이 아니라고 설명해야합니까? 그렇다면 어떻게해야합니까?

+0

작성한 코드는 해당 형식 (2012 년 1 월 7 일 00:00)으로 작업하고 첫 번째 줄을 읽어야합니다. 나는 빠른 테스트를했고 모든 라인을 읽었다. 그러나'try'와'except'가 반대로된다면, 첫 번째 라인을 놓치게 될 것이므로, 당신의 접근 방식은 좋지 않습니다. 내가 너라면 필자는 날짜 형식을 감지하고 파일의 시작 부분을 찾는다. (예 : 문서의 Sniffer 예제) 또한 형식을 미리 알고 있기 때문에 try/except를 피할 수 있습니다. 형식의 오류를 잡으려고 여전히 '시도'할 수 있습니다. –

+0

고맙습니다. 사실, 대부분의 입력은 YYYY-MM-DD hh : mm : ss 형식이므로 모든 형식을이 형식으로 변환하고 하나의 형식 만 읽습니다. 하지만 왜 시도는 ... 예외 : 행을 놓치지? – doctorer

답변

1

당신이 당신의 try, except 문을 실행하면 그 파이썬 것이다 첫번째 try 무언가를 믿기 쉽고, 실패 할 경우 다시 try 문이 실행되기 이전의 상태로 환경을 되돌립니다. 그것은 이것을하지 않습니다. 따라서 try 시도가 실패 할 때 발생할 수있는 의도하지 않은 부작용을 인식해야합니다.

귀하의 경우에는 사전 통역이 csv.reader() 개체()의 next(...) (이)가 호출되어 csv 파일의 첫 번째 줄을 반환합니다. 이제 csv.reader() 반복기의 첫 번째 항목을 다 사용했습니다. try 블록이 실패하면 파이썬은 이전 상태로 되돌아 가지 않습니다.

예외가 발생하면 날짜가 잘못된 형식으로 추정됩니다. 그런 다음 except 블록이 인계 받아 csv_in 개체에서 next(...)을 호출하면 이터레이터에서 두 번째 항목을 가져옵니다. 첫 번째는 이미 사용되었습니다.

이 문제를 해결하기위한 간단한 변경은 csv 반복기 개체의 복사본을 만드는 것입니다.

import datetime as dt 
import csv 
from copy import copy 
with open(fileInput,'r') as inFile: 
    csv_in = csv.reader(inFile) 
    try: 
     dictData = {(dt.datetime.strptime(rows[0],'%d/%m/%Y %H:%M')): 
         [rows[3],rows[4]] for rows in copy(csv_in)} 
    except ValueError: 
     dictData = {(dt.datetime.strptime(rows[0],'%Y-%m-%d %H:%M:%S')): 
         [rows[3],rows[4]] for rows in copy(csv_in)} 

마지막으로 일반 Exception을 잡는 것에 반대하는 것이 좋습니다. 나는 당신이 ValueError을 붙잡고 싶을 것이라고 생각합니다.

+0

고맙습니다 ... 저는 파이썬을 처음 접했고 정확하게 '시도'와 '예외'에 대한 오해가있었습니다. 이제 훨씬 더 명확 해졌습니다 – doctorer

+1

걱정할 필요가 없습니다. 이것이 우리 모두가 배우는 방법입니다. :) –