2017-05-15 15 views
1

*argsの機能を理解しようとするコードを作成しましたが、counter変数をリセットしないと問題が発生しています。ルーピングオーバー* argsカウンタをリセット

4番目の項目の後に、ナンバリングは0にリセットされますが、私はそれをargsを越えて継続します。

lst = ['apple', 'banana', 'orange', 'lemon'] 
lst2 = ['apple2', 'banana2', 'orange2', 'lemon2'] 
lst3 = ['apple3', 'banana3', 'orange3', 'lemon3'] 


def generateMenu(*args): 
    counter = 0 

    for i in args: 
     def recurse(l, counter): 
      for i in l: 
       counter += 1 
       if isinstance(i, (list, tuple)): 
        recurse(i, counter) 
       else: 
        print("{}. {}.".format(counter, i)) 
     recurse(i, counter) 


generateMenu(lst, lst2, lst3) 

出力:

1. apple. 
2. banana. 
3. orange. 
4. lemon. 
1. apple2. 
2. banana2. 
3. orange2. 
4. lemon2. 
1. apple3. 
2. banana3. 
3. orange3. 
4. lemon3. 
+0

あなたは再帰の第2引数を決して与えません。私はそれが間違いだと思うだろう。また、カウンター変数をシャドーイングしているという事実は、おそらくオフの動作を引き起こしています。パラメータと変数を異なる名前にします。 – Carcigenicate

+0

グローバルカウンタの使用はどうですか?最初にあなたの関数 'counter = 0'の外側を定義し、関数の最初の行を' global counter'に置き換えます。 – Mikael

+0

@Carcigenicate He *は 'recurse'の* outer *呼び出しでcounterを渡します。 *インナー* 1。そして、内部の場合は、与えられた入力で決して引き起こされることはありません。 – deceze

答えて

2

あなたは、代わり

lst = ['apple', 'banana', 'orange', 'lemon'] 
lst2 = ['apple2', 'banana2', 'orange2', 'lemon2'] 
lst3 = ['apple3', 'banana3', 'orange3', 'lemon3'] 


def generateMenu(*args): 
    counter = 0 

    for i in args: 
     def recurse(l): 
      nonlocal counter 
      for i in l: 
       counter += 1 
       if isinstance(i, (list, tuple)): 
        recurse(i) 
       else: 
        print("{}. {}.".format(counter, i)) 
     recurse(i) 


generateMenu(lst, lst2, lst3) 

(ローカル以外はのpython3で導入されました)counternonlocalを作るPythonは関数の外の変数への書き込みについて少し奇妙なルールがありrecurse

lst = ['apple', 'banana', 'orange', 'lemon'] 
lst2 = ['apple2', 'banana2', 'orange2', 'lemon2'] 
lst3 = ['apple3', 'banana3', 'orange3', 'lemon3'] 

def generateMenu(*args): 
    counter = 0 

    for i in args: 
     def recurse(l, counter): 
      for i in l: 
       counter += 1 
       if isinstance(i, (list, tuple)): 
        counter = recurse(i, counter) 
       else: 
        print("{}. {}.".format(counter, i)) 
      return counter 
     counter = recurse(i, counter) 


generateMenu(lst, lst2, lst3) 
+0

パーフェクト。両方とも問題なく試しました。どうもありがとうございました! –

1

問題は、あなたのrecurse機能は、上位のスコープからのごcounterを認識していないということです。だから、それぞれのfor i in l:ループで増加しているのは、単に "内側" counterの変数です。

同じ変数名を2回(counterおよびi)使用しているため、この例では混乱する可能性があります。別の方法で名前を変更しようとすると、コードで何が起こっているのかをよりよく知ることができます。

+0

ループを壊すことなく、どのように外側のスコープに '返す 'ことができますか? –

+0

John La Rooyの例のように、 'global/nonlocal'を定義するか、または' recurse'関数に外側の 'counter'を渡して、各ループの内部カウンタに追加するか、関数を変数に代入して返します。 – errata

1

からcounterを返す必要があります範囲。このIMOを避ける最も簡単な方法は、再帰関数が各状態でカウンタ値を返すことを確認することです。私は若干リファクタリングして、何が起こっているのかを少しはっきりさせました。

lst = [('apple', 'banana'), 'orange', 'lemon'] 
lst2 = ['apple2', 'banana2', 'orange2', 'lemon2'] 
lst3 = ['apple3', 'banana3', 'orange3', 'lemon3'] 


def generateMenu(*args): 
    outer_counter = 1 

    def recurse(l, inner_counter): 
     for i in l: 
      if isinstance(i, (list, tuple)): 
       inner_counter = recurse(i, inner_counter) 
      else: 
       print("{}. {}.".format(inner_counter, i)) 
       inner_counter += 1 
     return inner_counter 

    for i in args: 
     outer_counter = recurse(i, outer_counter) 


generateMenu(lst, lst2, lst3) 
関連する問題