2013-07-12 2 views
1

안녕하십니까, 문자열을 사용하여 for 루프를 사용하는 방법을 궁금합니다. 사용자,문자열과 함께 특정 범위의 "for 루프"를 사용할 수 있습니까?

파일 (file.txt를) 등이있다 예를 들어

,

=====================

Initial Value 

    1 2 3 
    3 4 5 
    5 6 7 

Middle Value   <---From Here 

    3 5 6 
    5 8 8 
    6 9 8     <---To Here 

Last Value 

    5 8 7 
    6 8 7 
    5 5 7 

================== 내가 출력 파일 만 "중간 값"에있는 파일의 부분을 수정하고 쓰고 싶은

에이 수정.

"if 및 for"문을 사용하면 해결할 수 있다고 생각합니다.

나는

with open('file.txt') as f, open('out.txt', 'w') as f2: 

     for line in f: 
      sp1 = line.split() 
      line = " ".join(sp1) + '\n' 
      if line == 'Middle': 
       "Do something until line == 'Last'" 

내가 "Do something until line == 'Last'" 부분에 붙어 같은 코드를 생각했다.

모든 의견을 환영합니다.

감사합니다.

+0

파일에 중간 값이라는 행이 항상 있음을 말하고 있습니까? – PyNEwbie

+0

"고정"을 정의 하시겠습니까? –

+1

거의 자신의 질문에 대답했습니다. while 루프를 사용해보십시오. –

답변

1

난 그냥 간단한 FSM과 공정 (더 구체적으로 Finite-State Machine 또는 event-driven Finite-state machine) 코드 것이다 :

with open('file.txt') as f, open('out.txt', 'w') as f2: 
    state = 1 
    for line in f: 
     if line == 'Middle Value\n': 
      state = 2 
      continue # unless there's something to do upon entering the state 
     elif line == 'Last Value\n': # might want to just test for blank line `\n' 
      state = 3 
      continue # unless there's something to do upon entering the state 

     # otherwise process to line based on the current value of "state" 
     if state == 1:  # before 'Middle Value' has been seen 
      pass 
     elif state == 2: # after 'Middle Value' has been seen 
      pass 
     else:    # after 'Last Value' (or a blank line after 
      pass   # 'Middle Value') has been seen 

그냥 읽기의 그 시점에서해야 할 적절한 무엇이든 함께 pass 문을 대체를 입력 파일

+0

이 코드를 사용할 때 한 가지를 제외하면 작동합니다. "continue"문은 출력 파일에서 '중간 값'및 '마지막 값'문자열을 삭제합니다. 수정 후 두 단어가 어떻게 남았습니까? –

+1

'continue'는'if state =='검사를 포함하여 루프의 반복에서 건너 뛸 모든 처리를 의미합니다. 후자가 일어나도록하기 위해 그것을 완전히 제거하거나 진술 전에해야 할 일을 다하십시오. – martineau

+0

나는 이것을 해결했다. 감사. –

0

내가 파일을 액세스 할 때 용서 조금 당신의 if line == 'Middle': 당신이 다음 번호를 수정할 수있는 다른 if inMiddle and line != last` 문을 입력 할 수있는 부울 플래그를 플립 수에서 다른

with open('file.txt') as f: 
    file_string = f.read() 

middle_to_end = file_string.split('Middle Value\n')[-1] 
just_middle = middle_to_end.split('Last Value\n')[0] 

middle_lines = just_middle.splitlines() 
for line in middle_lines: 
    do_something 
+0

'list.split' 메소드가 없습니다. – abarnert

+0

감사합니다 - 다른 것에주의를 기울였습니다 – PyNEwbie

+1

'just_middle.split()'은 줄 바꿈뿐만 아니라 공백을 나누기 때문에 '3', '5' 등의 줄을 사용하게됩니다. ''3 5 6 ''과 같은 줄 대신. 나는 당신이'splitlines'을 의미한다고 가정하고, 그래서 그것을 고쳤습니다. – abarnert

0

for 루프를 이것으로 대체 할 수 있습니다.

inMiddle = false 
for line in f: 
    sp1 = line.split() 
    line = "".join(sp1) + '\n' 

    if line == 'Middle': 
     inMiddle = true 

    if inMiddle and line != 'Last': 
     #MODIFY YOUR NUMBERS HERE 
    elif line == 'Last': 
     inMiddle = false 
3

세 가지 기본 접근 방식이 있습니다.


첫 번째는 상태 시스템을 사용하는 것입니다. 당신은 실제 상태 머신을 만들 수 있지만,이 경우 상태 및 전환은 그냥 플래그를 사용하여 가짜로 간단 너무 사소한 : 나는 'Middle\n'하지 'Middle' 검사

state = 0 
for line in f: 
    sp1 = line.split() 
    line = " ".join(sp1) + '\n' 
    if state == 0: 
     if line == 'Middle\n': 
      state = 1 
    elif state == 1: 
     if line == 'Last\n': 
      state = 2 
     else: 
      # Thing you do until line == 'Last\n' 
    else: 
     # nothing to do after Last, so you could leave it out 

참고. 위의 방법으로 보면 line을 작성하면 항상 '\n'을 추가하기 때문에 후자와 일치시킬 방법이 없습니다. 그러나 표본 데이터보다 더한 메모는 'Middle'이 아니라 'Middle Value\n'이되므로 실제 데이터에 해당되는 경우 여기에서 처리해야합니다. 그게 line == 'Middle Value\n', line.startswith('Middle') 또는 그 밖의 것이 실제 데이터에 달려 있습니다.


또는, 당신은 루프에 그것을 깰 수

for line in f: 
    sp1 = line.split() 
    line = " ".join(sp1) + '\n' 
    if line == 'Middle\n': 
     break 
for line in f: 
    sp1 = line.split() 
    line = " ".join(sp1) + '\n' 
    if line == 'Last\n': 
     break 
    else: 
     # Thing you do until line == 'Last\n' 
for line in f: 
    # Nothing to do here, so you could leave the loop out 

뿐만 아니라이 일에 변화가있다.예를 들어 :

lines = (" ".join(line.split()) + '\n' for line in f) 
lines = dropwhile(lambda line: line != 'Middle', lines) 
middle = takewhile(lambda line: line != 'End', lines) 
for line in middle: 
    # Thing you want to do 

마지막으로, 대신 이후의 라인으로 돌려 전에 파일 을 분할 할 수 있습니다. 이 아이디어를 보여주기 위해 메모리에 전체 파일을 반복적으로 수행 그래서 그냥 읽을 수 있도록 단단하다 :

contents = f.read() 
_, _, rest = contents.partition('\nMiddle\n') 
middle, _, _ = rest.partition('\nEnd') 
for line in middle.splitlines(): 
    # Thing you want to do 

메모리 폐기물 너무 많은 공간에 전체 파일을 읽는 경우 또는 너무 오래 당신이 가야하기 전에, mmap이 소요 네 친구.

+0

루프를 깨는 건 좋은 생각입니다. – Stephan

+0

@Stephan : 저는 이걸 읽을 수있게 만드는 것이 두 번째 단계라고 생각합니다. 플래그, 여러 내용을 반복하는 루프 또는 코드 대신 행의 문자로 파일을 처리하는 코드를 사용하는 경우 (마지막 예제에서와 같이 큰 파일 문제는 무시하지 않는 한) 추한 것입니다. . 그러나 세 가지 중 하나는 상태 시스템, 반복기 파이프 라인 또는 단순히 mmap을 통한 간단한 분할로 쉽게 추상화 될 수 있으며, 모두 읽을 수있게됩니다. – abarnert

+0

네, 단순한 솔루션이 존재하기 때문에 마지막 질문을 분석하는 것을 귀찮게하지 않았습니다. 그럼에도 불구하고이 스레드에는 좋은 아이디어가 많이 있으며 업보가별로 없기 때문에이 커뮤니티는 승인 클릭으로 인색합니다. – Stephan

0

기본적으로 '섹션'에 있음을 나타내는 플래그를 설정하고 있습니다. 아래에서 필자는 끝나면 선택적으로 다른 플래그를 설정합니다. 깃발이 2 일 때 보석금을 낼 수 있습니다.

with open('file.txt') as f, open('out.txt', 'w') as f2: 

    section = 0; 

    for line in f: 
     if line.startswith("Middle"): 
      section = 1 
     elif line.startswith("Last"): 
      section = 2 



     if section == 1: 
     #collect digits and output to other file  
     f2.write(line)   

     elif section == 2: 
     #close file and break out 
     f.close() 
     f2.close() 
     break 
     else: 
      continue 
+0

len (line)> 6과 line [: 6] == "Middle"'라고 쓰는 이유는 무엇입니까?첫째,'line [: 6] == "Middle"'는 더 짧은 것에 대해서 항상 거짓이되기 때문에 첫 번째 부분은 필요 없다. 둘째,'line.startswith ("Middle")'는 더 읽기 쉽고 견고합니다. 문자열의 길이를 계산하지 않아도 잘못 계산했거나 나중에 변경된 것이므로 버그가 생길 수 없습니다. – abarnert

관련 문제