EDIT: Adding in
upperline = []
lowerline = []
above the for
loop seems to allow the function to be called once as expected, but not more than once. If called a second time the following error will be thrown:
transitenergy = (float(upperline[1]) - float(lowerline[1]))
IndexError: list index out of range
If instead
upperline = [1,2]
lowerline = [4,5]
is added above the for
loop, the function returns the expected value the first time, and then -3 every other time.
I am having a problem with a for
loop seemingly being unable to retain variables when trying to return these variables, even though I can print the variables.
If I define the function as follows, when it is called , the transitenergy
will be printed to the console, and then the following error will be thrown:
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
I have also tried moving the return statement inside the loop i.e.
...
elif i == upperpointer:
upperline = filter(lambda a: a!= '\t',filterstring(line))
transitenergy = (float(upperline[1]) - float(lowerline[1]))
return transitenergy
or adding the return to a further elif
branch i.e.
...
elif i == upperpointer:
upperline = filter(lambda a: a!= '\t',filterstring(line))
elif i > upperpointer:
transitenergy = (float(upperline[1]) - float(lowerline[1]))
return transitenergy
but both of these just return a NoneType
when the function is called and throws TypeError: bad operand type for abs(): NoneType
when I try to call abs()
on it (as expected of a NoneType
).
The interesting part here, is if a print statement after defining the local transitenergy
variable, in any of the trials I have described, calling the function prints transitenergy
without a problem, and then throws the errors.
I should mention that the datafile used in the datafile
argument are very large files (on the order of 100+Mb) where each line has the structure:
" [line number+1] [float] ...."
(there are more numbers after this in the string but they are not relevant to the task)
The lookuppointers
argument are lists of the following structure:
[int, int, ...]
The integers are not ordered (hence the min
and max
) and refer to a [line number +1] of the datafile
The line:
filter(lambda a: a!= '\t',filterstring(line))
Is because I am iterating over a list of many of these files, and although they usually are in the correct format, and sometimes they will have a \t
at the beginning.
The filterstring
function is defined as:
def filterstring(string):
return filter(lambda a:a!='',string.split(" "))
to turn the line in the datafile
into a list of strings.
The question is how can I return the transitenergy
variable as it is printed.
If there is another way that I can perform this type of cross referencing without having the whole datafile
in memory then that would work also.