2015-01-26 1 views
1

CSV 파일을 스캔하고 줄 단위로 조정하려고합니다. 마지막으로 마지막 줄을 제거하고 싶습니다. 동일한 스캐닝 루프 내에서 마지막 라인을 제거하려면 어떻게합니까?Python은 파일을 한 줄씩 스캔하고 같은 루프에서 마지막 줄을 제거합니다.

아래 코드는 원본 파일을 읽고 조정 한 다음 마지막으로 새 파일에 씁니다.

import csv 

raw_data = csv.reader(open("original_data.csv", "r"), delimiter=",") 
output_data = csv.writer(open("final_data.csv", "w"), delimiter=",") 
lastline = # integer index of last line 

for i, row in enumerate(raw_data): 
    if i == 10: 
     # some operations 
     output_data.writerow(row) 
    elif i > 10 and i < lastline: 
     # some operations 
     output_data.writerow(row) 
    elif i == lastline: 
     output_data.writerow([]) 
    else: 
     continue 
+0

파일의 마지막 줄을 제거 하시겠습니까? 원래 입력 파일? – Evert

+0

@ output_data의 마지막 행을 제거하십시오. – Boxuan

+0

마지막 줄을 지우려면 왜 먼저 써야합니까? – Evert

답변

3

예 ... 확실하지 않음 :

for i, row in enumerate(remove_last_element(raw_data)): 
    # your code 

마지막 줄은 자동으로 무시됩니다.

이 접근 방식은 파일을 한 번만 읽는 이점이 있습니다.

0

아이디어는 "파일을 단축"이렇게 잘라 마지막 줄에 파일을 올 때 다음 반복하고 각 줄의 길이를 계산하는 것입니다. 당신은 단지에 raw_data 포장 그리고

def remove_last_element(iterable): 
    iterator = iter(iterable) 
    try: 
     prev = next(iterator) 
     while True: 
      cur = next(iterator) 
      yield prev 
      prev = cur 
    except StopIteration: 
     return 

이 좋은 연습하지만 경우에 당신은 마지막 하나를 제외한 모든 요소를 ​​산출하기 위해 발전기를 만들 수 있습니다 Python: truncate a file to 100 lines or less

0

대신, 현재의 행마다 루프 반복을 작성하는, 이전에 읽은 라인을 작성하려고 : 당신은 창 크기를 2 및 인쇄 첫 번째 값의 창 반복 할 수

import csv 

raw_data = csv.reader(open("original_data.csv", "r"), delimiter=",") 
output_data = csv.writer(open("final_data.csv", "w"), delimiter=",") 
last_iter = (None, None) 

try: 
    last_iter = (0, raw_data.next()) 
except StopIteration: 
    # The file is empty 
    pass 
else: 
    for new_row in raw_data: 
     i, row = last_iter 
     last_iter = (i + 1, new_row) 

     if i == 10: 
      # some operations 
      output_data.writerow(row) 
     elif i > 10: 
      # some operations 
      output_data.writerow(row) 

    # Here, the last row of the file is in the `last_iter` variable. 
    # It won't get written into the output file. 
    output_data.writerow([]) 
1

. 이 마지막 요소는 생략되는으로 이어질 것입니다 :

from itertools import izip, tee 

def pairwise(iterable): 
    a, b = itertools.tee(iterable) 
    next(b, None) 
    return izip(a, b) 

for row, _ in pairwise(raw_data): 
    output_data.writerow(row) 

output_data.writerow([]) 
+0

이 메서드는 목록 곱셈이 참조를 복사한다는 사실을 이용하므로 동일한 반복자에 대한 참조 쌍이되며 각 루프마다 두 배로 빠르게 증가합니다. –

+0

@kroolik 답변을 수정했습니다. 그것은 그루퍼가 아니라 '쌍벌'이어야합니다. 감사! – ovgolovin

2

@Kolmar's idea의 변화 :

import itertools, collections 

def islice2(it, stop): 
    if stop >= 0: 
     for x in itertools.islice(it, stop): 
      yield x 
    else: 
     d = collections.deque(itertools.islice(it, -stop)) 
     for item in it: 
      yield d.popleft() 
      d.append(item) 


for x in islice2(xrange(20), -5): 
    print x, 

# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 
:

def all_but_last(it): 
    buf = next(it) 
    for item in it: 
     yield buf 
     buf = item 

for line in all_but_last(...): 

여기에 부정적인 인덱스에 대한 islice (두 인수 버전)을 확장보다 일반적인 코드입니다

+0

그건 좋은 수정이야,'itertools.islice'도 선택적인'start'와'step' 매개 변수를 가지고 있다는 것을 염두에 두십시오 – Kolmar

+0

@Kolmar : 그래,하지만 너무 게으르다.)'islice2 (xs, 100, 0, -5) '는 많은 일처럼 들린다. – georg

관련 문제