Reputation: 2431
I'm working on some made up code to try to understand *args
functionality and am having difficulty getting my counter
variable to not reset.
After the 4th item, the numbering resets back to 0, but I want it to continue across the 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)
Output:
1. apple.
2. banana.
3. orange.
4. lemon.
1. apple2.
2. banana2.
3. orange2.
4. lemon2.
1. apple3.
2. banana3.
3. orange3.
4. lemon3.
Upvotes: 1
Views: 58
Reputation: 99
Python has slightly odd rules about writing to variables outside of the function's scope. The easiest way to avoid this IMO is just to make sure that your recursive function returns the counter value at each state. I've slightly refactored to make it a bit clearer what is going on.
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)
Upvotes: 1
Reputation: 304473
You should make counter
a nonlocal
(nonlocal was introduced in Python3)
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)
Alternatively, return counter
from 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)
Upvotes: 2
Reputation: 6041
The problem is that your recurse
function is not aware of your counter
from upper scope. So what you are increasing in each for i in l:
loop is just the "inner" counter
variable.
Your example might confuse you because you are using same variable names twice (counter
and i
). Try to rename them in a different way and you might get a better idea of what is happening with your code.
Upvotes: 1