【问题标题】:How to skip N central lines when reading file?读取文件时如何跳过N条中心线?
【发布时间】:2020-11-05 11:33:02
【问题描述】:

我有一个像这样的输入 file.txt:

3
2
A
4
7
B
1
9
5
2
0       

我正在尝试读取文件并且

  • 找到A时,打印下面两行的行
  • 找到B后,打印下面4行的那一行

我当前的代码和当前输出如下:

with open('file.txt') as f:
    for line in f:
        if 'A' in line: ### Skip 2 lines!
            f.readline()        ### Skipping one line
            line = f.readline() ### Locate on the line I want
            print(line) 
        if 'B' in line: ## Skip 4 lines
            f.readline()        ### Skipping one line
            f.readline()        ### Skipping two lines
            f.readline()        ### Skipping three lines
            line = f.readline() ### Locate on the line I want
            print(line)             
        
'4\n'
7

'1\n'
'9\n'
'5\n'
2       
>>>

正在打印我想要的值,但也在打印4\n,1\n...,除此之外,我还需要写几个f.realines(),这是不实用的。

有没有更好的方法来做到这一点?

我的预期输出是这样的:

7
2

【问题讨论】:

  • 你是如何运行代码的?如果您使用的是 IPython 或 Jupyter 笔记本,这可能就是您获得额外输出的原因,因为我看不出有任何理由 '1\n' 会根据您拥有的代码在输出中显示。
  • 我无法重现您所描述的内容。唯一的事情是它打印包含换行符的行(7 和 2)。您可以使用 line.strip() 剥离结果行
  • 没有第一条评论:尝试使用虚拟变量“消费”f.readline()_ = f.readline()
  • 我在 Ubuntu shell 上以测试模式运行它。

标签: python-3.x text-files readline


【解决方案1】:

如果你不喜欢重复的readline,那就把它包装在一个函数中,这样剩下的代码就很干净了:

def skip_ahead(it, elems):
    assert elems >= 1, "can only skip positive integer number of elements"
    for i in range(elems):
        value = next(it)
    return value

with open('file.txt') as f:
    for line in f:
        if 'A' in line:
            line = skip_ahead(f, 2)
            print(line) 
        if 'B' in line:
            line = skip_ahead(f, 4)
            print(line)             
    

至于额外的输出,当您提供的代码在标准 python 解释器中运行时,只有 print 语句会导致输出,因此没有像 '1\n' 这样的额外行,这是某些上下文的功能,例如当在语句上下文中找到表达式时的 IPython shell,在这种情况下,f.readline() 单独在它自己的行上,因此它被检测为可能具有可能有趣的值。要抑制这种情况,您可以经常使用_ = <expr> 来抑制输出。

【讨论】:

    【解决方案2】:

    这里有一个更简单的代码:

    lines=open("file.txt","r").read().splitlines()
    #print(str(lines))
    for i in range(len(lines)):
        if 'A' in lines[i]:
            print(lines[I+2]) # show 2 lines down
        elif 'B' in lines[i]:
            print(lines[I+4]) # show 4 lines down
    
    

    这会将整个文件读取为一个数组,其中每个元素都是文件的一行。然后它只是遍历数组并在找到它正在寻找的行时直接将索引更改为 2(对于 A)和 4(对于 B)。

    【讨论】:

    • 请注意,在更改 i 之后,这实际上并没有跳过迭代中的那些行。迭代 for 循环将返回并遍历跳过的每一行,这与迭代文件的原始代码不同。在这种简单的情况下不一定是坏事,但假设代码中发生了更复杂的事情,这可能会导致非常细微的差异。
    • 非常感谢您的解决方案。它可以在某些情况下工作。问候
    猜你喜欢
    • 1970-01-01
    • 2013-03-25
    • 1970-01-01
    • 2011-12-13
    • 2018-08-20
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多