我可以打印一个局部变量但不返回它(python 2.7)

时间:2016-09-13 12:13:09

标签: python python-2.7 function for-loop

编辑: 加入

upperline = []
lowerline = []
for循环上方的

似乎允许按预期调用一次函数,但不能超过一次。如果第二次调用,将抛出以下错误:

transitenergy = (float(upperline[1]) - float(lowerline[1]))
IndexError: list index out of range

如果是

upperline = [1,2]
lowerline = [4,5]

添加在for循环之上,函数第一次返回预期值,然后每隔一次返回-3。

我遇到问题,for循环在尝试返回这些变量时似乎无法保留变量,即使我可以打印变量。 如果我按如下方式定义函数,当它被调用时,transitenergy将被打印到控制台,然后将抛出以下错误:

transitenergy = (float(upperline[1]) - float(lowerline[1]))

UnboundLocalError: local variable 'upperline' referenced before assignment"

def crossreference(datafile, lookuppointers):
    pointers = [(int(lookuppointers[0]) - 1), (int(lookuppointers[1]) - 1)]
    lowerpointer = min(pointers)
    upperpointer = max(pointers)
    for i, line in enumerate(datafile):
        if i == lowerpointer:
            lowerline = filter(lambda a: a!= '\t',filterstring(line))
        elif i == upperpointer:
            upperline = filter(lambda a: a!= '\t',filterstring(line))
            break
    transitenergy = (float(upperline[1]) - float(lowerline[1]))]
    print transitenergy
    return transitenergy

我也试过在循环中移动return语句,即

...
elif i == upperpointer:
    upperline = filter(lambda a: a!= '\t',filterstring(line))
    transitenergy = (float(upperline[1]) - float(lowerline[1]))
    return transitenergy

或将回报添加到另一个elif分支,即

...
elif i == upperpointer:
    upperline = filter(lambda a: a!= '\t',filterstring(line))
elif i > upperpointer:
    transitenergy = (float(upperline[1]) - float(lowerline[1]))
    return transitenergy

但是这两个函数在调用函数时只返回NoneType,当我尝试在其上调用TypeError: bad operand type for abs(): NoneType时抛出abs()(正如预期的NoneType) 。

这里有趣的部分是,如果在定义本地transitenergy变量之后的print语句,在我描述的任何试验中,调用函数打印transitenergy没有问题,然后抛出错误。

我应该提一下datafile参数中使用的数据文件是非常大的文件(大约100 + Mb),其中每一行都有结构:

"           [line number+1]     [float]      ...." 

(字符串后面有更多数字,但它们与任务无关)

lookuppointers参数是以下结构的列表:

[int, int, ...]

整数未被排序(因此minmax)并且引用datafile

的[行号+1]

该行:

filter(lambda a: a!= '\t',filterstring(line))

是因为我正在迭代许多这些文件的列表,虽然它们通常格式正确,但有时它们的开头会有\t

filterstring函数定义为:

def filterstring(string):
    return filter(lambda a:a!='',string.split(" "))

datafile中的行转换为字符串列表。

问题是如何在打印时返回transitenergy变量。

如果还有另一种方法可以执行这种类型的交叉引用,而内存中没有整个datafile,那么这也可以。

1 个答案:

答案 0 :(得分:0)

解决方案在于数据文件保持打开。将行datafile.seek(0)添加到函数中,即

def crossreference(datafile, lookuppointers):
    pointers = [(int(lookuppointers[0]) - 1), (int(lookuppointers[1]) - 1)]
    lowerpointer = min(pointers)
    upperpointer = max(pointers)
    datafile.seek(0)
    for i, line in enumerate(datafile):
        if i == lowerpointer:
            lowerline = filter(lambda a: a!= '\t',filterstring(line))
        elif i == upperpointer:
            upperline = filter(lambda a: a!= '\t',filterstring(line))
            transitenergy = (float(upperline[1]) - float(lowerline[1]))
            return transitenergy

每次调用函数时都会从头开始读取文件,而不是从读取文件的最后一个位置读取文件之前发生的事情。