【问题标题】:Iterating through N lines in a for loop before moving on to next loop在进入下一个循环之前在 for 循环中迭代 N 行
【发布时间】:2016-11-11 09:28:05
【问题描述】:

我在How to interate over N lines of a text file in Python 上发布了一个问题,但我想让程序更适用于 N 行(例如,我不想一次收集两行,而是一次收集四到六行。

我要转这个 disp.txt :

116  C             0.12 -0.91  0.39    -0.40  0.31  0.85    -0.66 -0.18 -0.22
117  O             0.00 -0.02  0.00    -0.05  0.05  0.12    -0.57 -0.26 -0.29
116  C            -0.03 -0.04  0.00     0.01  0.09  0.19    -0.71 -0.21 -0.26
117  O            -0.14  0.88 -0.45     0.47 -0.33 -0.79     0.57  0.16  0.19

对此:

vibration 1
0.12  -0.91  0.39
0.0  -0.02  0.0
vibration 2
-0.4  0.31  0.85
-0.05  0.05  0.12
vibration 3
-0.66  -0.18  -0.22
-0.57  -0.26  -0.29
vibration 4 
-0.03 -0.04 0.00 
-0.14 0.88 -0.45
vibration 5 ...

以下是我目前所拥有的

vibration = 1
with open('disp1.txt','r') as f, open('disp2.txt', 'w') as out:

 while True:
  next_lines = list(islice(f,2))
  m = next_lines
  for i in m:
   s = i.strip().split('\n')
   for j in s:
    p = j.split()
    v = len(p)
    for u in range(2,5,3):
     out.write('vibration {}\n'.format(vibration))
     out.write(' '.join(p[u:u+3])+'\n')
     vibration += 1
    for x in range(5,8,3):
     out.write(' '.join(p[x:x+3])+'\n')
    for y in range(8,11,3):
      out.write(' '.join(p[y:y+3])+'\n')
  if not next_lines:
   break

显示这个:

vibration 1
0.12 -0.91 0.39
-0.40 0.31 0.85
-0.66 -0.18 -0.22
vibration 2
0.00 -0.02 0.00
-0.05 0.05 0.12
-0.57 -0.26 -0.29
vibration 3
-0.03 -0.04 0.00
0.01 0.09 0.19
-0.71 -0.21 -0.26
vibration 4
-0.14 0.88 -0.45
0.47 -0.33 -0.79
0.57 0.16 0.19

所以它是在整个页面上阅读,而不是阅读前三列数字的前两行,然后继续阅读下一组三,依此类推。 通过使用 isplice 它一次读取两行,但由于我不明白的原因,这两行都没有通过第一个循环(对于 u in range(2,5,3):),然后再进入下一个循环(对于x 在范围(5,8,3):) 相反,每一行都通过每个循环。 谁能帮我解决这个问题?

谢谢。

【问题讨论】:

  • 但是 0.12 -0.91 0.39 -0.40 0.31 0.85 -0.66 -0.18 -0.22 是一行!
  • 我的回答有用吗?如果是,请将其标记为正确(绿色复选)。
  • 嗨 Dani,因为我有六次振动,但你给我看的却是三个,那我就得再重复你写的三遍,对吧?如果是这种情况,我会尽量避免为我所拥有的每个不同数量的振动手动执行此操作。
  • 您的目标是拥有一份打印声明吗?

标签: python-2.7 python-3.x for-loop


【解决方案1】:

这应该做你想做的。

def group(lst, size = 3):
    """
    returns a list of lists where the inner lists are at most
    of length size

    [1, 2, 3, 4, 5, 6] -> [[1, 2, 3], [4, 5, 6]]
    group(list, int) -> list<list>
    """
    return [lst[i:i+size] for i in range(0, len(lst), size)]

def get_vibrations(lines):
    for vibration in zip(*[group(line) for line in lines]):
        yield '\n'.join(' '.join(v) for v in vibration)

def main(n):
    with open('in.txt', 'r') as fin, open('out.txt', 'w') as fout:
        i = 0
        for line in fin:
            line = line.strip().split()[2:]
            vibrations = [line] + [fin.readline().strip().split()[2:] for _ in range(n - 1)]

            # write each vibration to the file
            for i, v in enumerate(get_vibrations(vibrations), start = i + 1):
                fout.write('vibration {}\n{}\n'.format(i, v))

if __name__ == '__main__':
    main(4) # the number of lines per vibration

# Input
116  C             0.12 -0.91  0.39    -0.40  0.31  0.85    -0.66 -0.18 -0.22
117  O             0.00 -0.02  0.00    -0.05  0.05  0.12    -0.57 -0.26 -0.29
116  C            -0.03 -0.04  0.00     0.01  0.09  0.19    -0.71 -0.21 -0.26
117  O            -0.14  0.88 -0.45     0.47 -0.33 -0.79     0.57  0.16  0.19
116  C             0.26 -0.40 -0.83     0.26  0.31  0.25     0.33  0.71 -0.51
117  O            -0.19 -0.39 -0.36    -0.40  0.87  0.49     0.11  0.26 -0.57
116  C            -0.35  0.27  0.79    -0.03 -0.71 -0.18     0.93 -0.89 -0.81
117  O            -0.84  0.99  0.38    -0.27 -0.33  0.55     0.31  0.99 -0.18
116  C             0.76 -0.77  0.71     0.19 -0.39  0.46     0.30 -0.15  0.71
117  O            -0.97  0.31  0.58    -0.42  0.16 -0.33    -0.39 -0.17 -0.54

# Output
vibration 1
0.12 -0.91 0.39
0.00 -0.02 0.00
-0.03 -0.04 0.00
-0.14 0.88 -0.45
vibration 2
-0.40 0.31 0.85
-0.05 0.05 0.12
0.01 0.09 0.19
0.47 -0.33 -0.79
vibration 3
-0.66 -0.18 -0.22
-0.57 -0.26 -0.29
-0.71 -0.21 -0.26
0.57 0.16 0.19
vibration 4
0.26 -0.40 -0.83
-0.19 -0.39 -0.36
-0.35 0.27 0.79
-0.84 0.99 0.38
vibration 5
0.26 0.31 0.25
-0.40 0.87 0.49
-0.03 -0.71 -0.18
-0.27 -0.33 0.55
vibration 6
0.33 0.71 -0.51
0.11 0.26 -0.57
0.93 -0.89 -0.81
0.31 0.99 -0.18

如果你还想允许没有足够的行,那么你可以添加

from itertools import zip_longest

然后改成这个

def get_vibrations(lines):
    for vibration in zip_longest(*[group(line) for line in lines], fillvalue = ['null']):
        yield '\n'.join(' '.join(v) for v in vibration)

# Outputs | added to above output
vibration 7
0.76 -0.77 0.71
-0.97 0.31 0.58
null
null
vibration 8
0.19 -0.39 0.46
-0.42 0.16 -0.33
null
null
vibration 9
0.30 -0.15 0.71
-0.39 -0.17 -0.54
null
null

【讨论】:

  • 当我以每次振动的行数为 2 运行脚本时,我得到: Traceback(最近一次调用最后一次):文件“检查”,第 29 行,在 main(2) # the每次振动的行数文件“检查”,第 22 行,主振动 = [line] + [fin.readline().strip().split()[2:] for _ in range(n - 1)] ValueError : 混合迭代和读取方法会丢失数据
  • 我会仔细阅读你的脚本,看看我是否能更好地理解它,谢谢。
  • 这很奇怪,我没有收到任何错误。你用的是什么python版本,3?您是只尝试我的代码还是先尝试将其实现到您的代码中?
  • 澄清一下,您是否希望能够选择每次振动的行数还是应该始终为 2?
  • 您好,史蒂文,抱歉耽搁了。我已经离开了。我希望每次振动都能选择尽可能多的线。我尝试了您的代码并尝试在我的代码中实现它,但在使用 2.3 版时遇到了同样的错误。但是根据您的评论,当我使用第 3 版时,我没有收到任何错误。
【解决方案2】:
info = '''0.12 -0.91  0.39    -0.40  0.31  0.85    -0.66 -0.18 -0.22    0.00 -0.02  0.00    -0.05  0.05  0.12    -0.57 -0.26 -0.29    -0.03 -0.04  0.00    0.01  0.09  0.19    -0.71 -0.21 -0.26    -0.14  0.88 -0.45    0.47 -0.33 -0.79     0.57  0.16  0.19'''

new_list_1 = info.split('    ')
vib_1 = new_list_1[0] + '\n' + new_list_1[3]
vib_1 = 'vibration 1' + '\n' + vib_1
print vib_1

new_list_2 = info.split('    ')
vib_2 = new_list_2[1] + '\n' + new_list_2[4]
vib_2 = 'vibration 2' + '\n' + vib_2
print vib_2

new_list_3 = info.split('    ')
vib_3 = new_list_3[2] + '\n' + new_list_3[5]
vib_3 = 'vibration 3' + '\n' + vib_3
print vib_3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-11
    • 1970-01-01
    • 2020-07-17
    • 1970-01-01
    • 1970-01-01
    • 2020-10-21
    • 2019-11-28
    • 1970-01-01
    相关资源
    最近更新 更多