Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 取消文件上的最后一行迭代_Python_Python 3.x_For Loop_File Io - Fatal编程技术网

Python 取消文件上的最后一行迭代

Python 取消文件上的最后一行迭代,python,python-3.x,for-loop,file-io,Python,Python 3.x,For Loop,File Io,我需要对一个文件进行迭代,停止对某个条件的迭代,然后使用另一个函数在同一行继续解析该文件(这可能会发生变化,因此我不能只在前一个函数中添加内容) 示例文件(file.txt): 我尝试执行的功能: def parse1(file, stop): # 1st parsing function (Main function I am doing) for line in file: if line.strip() == stop: # Stop

我需要对一个文件进行迭代,停止对某个条件的迭代,然后使用另一个函数在同一行继续解析该文件(这可能会发生变化,因此我不能只在前一个函数中添加内容)

示例文件(file.txt):

我尝试执行的功能:

def parse1(file, stop):
# 1st parsing function (Main function I am doing)
    for line in file:
            if line.strip() == stop:
            # Stop parsing on condition
                break
            else:
            # Parse the line (just print for example)
                print(line)

def parse2(file):
# 2nd parsing function (Will be my own functions or external functions)
    for line in file:
        # Parse the line (just print for example)
        print(line)
导致终端:

>>> file = open("file.txt")

>>> parse1(file, "4")
1
2
3

>>> parse2(file)
5
6
7
8
9
我的问题是,当我查找条件时,第一个函数跳过了“4”行

如何避免这种情况:我找到了取消上一次迭代或返回一行的解决方案

file.tell()
函数不适用于文件上的
for

我尝试在
时使用
+
file.readline()
执行此操作,但它比
for
在文件上循环的速度要慢得多(我想解析具有数百万行的文件)


是否有一个优雅的解决方案来保持
for
循环的使用?

在python3中,“for line In file”构造在内部由迭代器表示。根据定义,从迭代器生成的值不能“放回”供以后使用()

要获得所需的行为,您需要一个将两个迭代器链接在一起的函数,例如
itertools
模块提供的函数。在
parse1
的停止条件下,返回最后一行以及文件迭代器:

import itertools

def parse1(file,stop):
# 1st parsing function
    for line in file:
       # Stop parsing on condition
        if line.strip() == stop:
            return itertools.chain([line],file) # important line
        else:
        # Parse the line (just print for example)
            print('parse1: '+line)
chain语句连接两个迭代器。第一个迭代器只包含一个元素:要再次处理的行。第二个迭代器是文件的剩余部分。一旦第一个迭代器的值用完,就会访问第二个迭代器

您不需要更改
parse2
。为了清楚起见,我修改了打印语句:

def parse2(file):
# 2nd parsing function
for line in file:
    # Parse the line (just print for example)
    print('parse2: '+line)
然后,您可以以最实用的方式调用parse1和parse2:

with open('testfile','r') as infile:
   parse2(parse1(infile,'4'))
上述行的输出为:

parse1: 1
parse1: 2
parse1: 3
parse2: 4
parse2: 5
parse2: 6
parse2: 7
parse2: 8
parse2: 9
注意,值“4”是如何由
parse2
函数生成的。

我建议对您的文件对象创建一个copy1,然后在
else
块中迭代该副本,并在第一个函数中调用第二个函数,另外,作为一种更具python风格的方式,您可以使用
with
语句打开文件,该文件将在语句末尾关闭文件,并将第二个函数放入第一个函数中:

#ex.txt

1
2
3
4
5
6
7
8
9
10
您可以使用创建文件对象的copy1:

from itertools import tee

def parse1(file_name, stop):

  def parse2(file_obj):
    print '**********'
    for line in file_obj:
        print(line)

  with open(file_name) as file_obj:
    temp,file_obj=tee(file_obj)
    for line in temp:
            if line.strip() == stop:
                break
            else:
                next(file_obj)
                print(line)
    parse2(file_obj)

parse1("ex.txt",'4')
结果:

1

2

3

**********
4

5

6

7

8

9

10

1) 实际上,
itertools.tee
并不创建副本,但您可以基于DOC将其用于此目的,它从单个iterable返回n个独立的迭代器。 您可以将其中一个独立迭代器分配给已迭代的对象本身,并将另一个迭代器创建为temp。
IMHO,最简单的解决方案是让第一个解析器返回找到停止条件的行,并将其传递给第二个解析器。第二个应具有解析一行的显式函数,以避免代码重复:

def parse1(file, stop):
# 1st parsing function (Main function I am doing)
    for line in file:
            if line.strip() == stop:
            # Stop parsing on condition
                return line
            else:
            # Parse the line (just print for example)
                print(line)
    return None

def parse2(file, line = None):
# 2nd parsing function (Will be my own functions or external functions)
    def doParse(line):
    # do actual parsing (just print for example)
        print(line)
    if line is None:
        doParse(line)
    for line in file:
        doParse(line)

# main
...
stop = parse1(file)
if stop:
    parse2(stop, file)

你能不能保留parse1中的line变量并将其传递给parse2这个想法对我自己的函数很好,但是我可以使用一些外部函数来代替没有类似参数的
parse2
。谢谢,这正是我需要的!这个想法适用于我自己的函数,但如果我想使用一些外部函数来代替没有这样参数的parse2,就不要这样做。@Anc欢迎,我认为将函数放在一个函数中更有效、更安全!我同意只生成一个函数更有效,但对于我的情况,我需要灵活性(我想要解析的文件类型可能会有所不同)。
def parse1(file, stop):
# 1st parsing function (Main function I am doing)
    for line in file:
            if line.strip() == stop:
            # Stop parsing on condition
                return line
            else:
            # Parse the line (just print for example)
                print(line)
    return None

def parse2(file, line = None):
# 2nd parsing function (Will be my own functions or external functions)
    def doParse(line):
    # do actual parsing (just print for example)
        print(line)
    if line is None:
        doParse(line)
    for line in file:
        doParse(line)

# main
...
stop = parse1(file)
if stop:
    parse2(stop, file)