有没有办法在字符串的特定范围内使用“for loop”?

时间:2013-07-12 17:43:52

标签: python file if-statement for-loop

您好stackoverflow用户,

我想知道如何使用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 and 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'"部分困住了。

任何评论都表示赞赏。

感谢。

5 个答案:

答案 0 :(得分:3)

有三种基本方法。


首先是使用状态机。你可以构建一个真正的状态机,但在这种情况下,状态和转换是如此微不足道,以至于只使用一个标志来伪造它就更简单了:

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

请注意,我检查了'Middle\n',而不是'Middle'。如果你看一下上面构建line的方式,就无法匹配后者,因为你总是添加'\n'。但请注意,与您的示例数据相比,该行为'Middle Value\n',而不是'Middle',因此如果您的实际数据中的情况属实,则必须在此处理。是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就是你的朋友。

答案 1 :(得分: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语句替换为在读取输入文件时适当的操作。

答案 2 :(得分:0)

请原谅我访问文件的方式有点不同

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

答案 3 :(得分:0)

在你的if line == 'Middle':中你可以翻转一个布尔标志,允许你输入另一个if inMiddle and line !=姓氏语句,然后你可以修改你的数字

您可以用此替换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

答案 4 :(得分: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