2016-09-13 5 views
0

: はforループ上私はローカル変数を印刷し、それを返すことはできません(のpython 2.7)EDIT

upperline = [] 
lowerline = [] 

に追加するにはなく、複数回、期待通りの機能は一度呼び出すことができるように思えます。呼び出された場合、第二時間は、次のエラーがスローされます:

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 

を私も持っています

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

すなわち、ループ内でreturn文を移動したり、さらにへの復帰を追加してみました枝すなわち

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

が、これらの両方が、ちょうど私が(NoneTypeの予想通り)、それにabs()を呼び出すしようとすると、関数が呼び出されるとTypeError: bad operand type for abs(): NoneTypeをスローされNoneTypeを返します。

ローカルtransitenergy変数を定義した後のprintステートメントで、私が説明した試行のいずれかで、関数print transitenergyを問題なく呼び出し、エラーをスローします。

私はdatafile引数で使用されるデータ・ファイルの各行は、構造を有している(100 + Mbの程度)、非常に大きなファイルであることを言及する必要があります:

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

(以上の数字は、この中の後にあります文字列ではなく、彼らは仕事に関係のない)

lookuppointers引数には、次のような構造のリストである:

[int, int, ...] 

の整数は行を(それゆえminmax)注文しdatafile

の[行番号1]を参照されていない:私は多くのリストを反復処理していますので

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

ですこれらのファイルのうち、通常は正しい形式になっていますが、冒頭に\tが表示されることがあります。文字列のリストにdatafileにラインをオンにする

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

filterstring関数は次のように定義されています。

質問は、transitenergyという変数を印刷する際にどのように返すことができますか?

メモリ内にdatafile全体を持たずにこのタイプの相互参照を実行できる別の方法がある場合は、それも機能します。

+2

'upperline'は' elif'ブランチでのみ定義されています。その定義は与えられていません –

+0

なぜブランチの外側で印刷できますか? – Positive

+0

さらに、問題を解決するには、これを修正するために、上線と下線の両方をグローバル変数として宣言する必要がありますか?あるいは、forループの前にupperline = []とlowerline = []のように定義していますか? @MosesKoledoye – Positive

答えて

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 

すなわち関数にラインdatafile.seek(0)を追加すると、ファイルは最初からファイルはそれがあった最後の場所から読まれていた場所の前に起こっていたこととは対照的に、関数が呼び出されたたびに読み込まれる原因となりましたから読んでください。

関連する問題