Local variables persist in functions?

1

120psi

I'm a bit baffled. Here is a bit of fairly straightforward code:

def _chunkify( l, chunkSize, _curList = list() ):
print _curList # yay for printf debugging
if len( l ) <= chunkSize:
_curList.append( l )
else:
newChunk = l[:chunkSize]
_curList.append( newChunk )
_chunkify( l[chunkSize:], chunkSize, _curList )
return _curList

_chunkify simply breaks a sequence into a sequence of smaller lists of
size <= chunkSize. The first call works fine, but if I call it
multiple times, weirdness happens.

chunks = _chunkify( list, size ) # _curList keeps its previous value!
chunks = _chunkify( list, size, list() ) # this works as expected

Considering the default value of _curList, these statements should be
identical. Any pointers? Did I miss something in the python reference
manual? (running 2.4.3, fyi)

Thanks,
Nils
 
J

John Machin

I'm a bit baffled. Here is a bit of fairly straightforward code:

def _chunkify( l, chunkSize, _curList = list() ):

Quite apart from the default argument problem, which Duncan has
addressed, you have some problems with style and variable names. In
particular: give variables meaningful names ; "L".lower() is not
meaningful and also suffers from confusion with the digit 1 in some
fonts. There is no necessity for the _ in _curList in the above line.

Please consider reading http://www.python.org/dev/peps/pep-0008/
print _curList # yay for printf debugging
if len( l ) <= chunkSize:
_curList.append( l )
else:
newChunk = l[:chunkSize]
_curList.append( newChunk )
_chunkify( l[chunkSize:], chunkSize, _curList )
return _curList

_chunkify simply breaks a sequence into a sequence of smaller lists of
size <= chunkSize. The first call works fine, but if I call it
multiple times, weirdness happens.

chunks = _chunkify( list, size ) # _curList keeps its previous value!
chunks = _chunkify( list, size, list() ) # this works as expected

Is the first "list" a list, or is it the name of the same function that
you are calling to provide the 3rd argument?

[snip]

HTH,
John
 
R

robert

I'm a bit baffled. Here is a bit of fairly straightforward code:

def _chunkify( l, chunkSize, _curList = list() ):
print _curList # yay for printf debugging
if len( l ) <= chunkSize:
_curList.append( l )
else:
newChunk = l[:chunkSize]
_curList.append( newChunk )
_chunkify( l[chunkSize:], chunkSize, _curList )
return _curList

_chunkify simply breaks a sequence into a sequence of smaller lists of
size <= chunkSize. The first call works fine, but if I call it
multiple times, weirdness happens.

chunks = _chunkify( list, size ) # _curList keeps its previous value!
chunks = _chunkify( list, size, list() ) # this works as expected

Considering the default value of _curList, these statements should be
identical. Any pointers? Did I miss something in the python reference
manual? (running 2.4.3, fyi)

the default list() is only created once when the function is defined. And its later its always the same list
Use

def _chunkify( l, chunkSize, _curList=None ):
_curList = _curList or []
...

then it works.

Robert
 
F

Fredrik Lundh

chunks = _chunkify( list, size ) # _curList keeps its previous value!
chunks = _chunkify( list, size, list() ) # this works as expected

Considering the default value of _curList, these statements should be
identical. Any pointers?
http://effbot.org/pyfaq/why-are-default-values-shared-between-objects.htm

Did I miss something in the python reference manual? (running 2.4.3, fyi)

the paragraph that starts with "Default parameter values are evaluated when
the function definition is executed." in bold, perhaps. I've highlighted it
on this page:

http://effbot.org/pyref/def.htm

</F>
 
1

120psi

John said:
I'm a bit baffled. Here is a bit of fairly straightforward code:

def _chunkify( l, chunkSize, _curList = list() ):

Quite apart from the default argument problem, which Duncan has
addressed, you have some problems with style and variable names. In
particular: give variables meaningful names ; "L".lower() is not
meaningful and also suffers from confusion with the digit 1 in some
fonts. There is no necessity for the _ in _curList in the above line.

Please consider reading http://www.python.org/dev/peps/pep-0008/
print _curList # yay for printf debugging
if len( l ) <= chunkSize:
_curList.append( l )
else:
newChunk = l[:chunkSize]
_curList.append( newChunk )
_chunkify( l[chunkSize:], chunkSize, _curList )
return _curList

_chunkify simply breaks a sequence into a sequence of smaller lists of
size <= chunkSize. The first call works fine, but if I call it
multiple times, weirdness happens.

chunks = _chunkify( list, size ) # _curList keeps its previous value!
chunks = _chunkify( list, size, list() ) # this works as expected

Is the first "list" a list, or is it the name of the same function that
you are calling to provide the 3rd argument?

[snip]

HTH,
John
Done. Veru useful, thank you. Even though it's not the most correct
way or using the leading _, I was using it to sort of say 'don't set
this when calling', and yes--"L" is a bad name for a list, and I
probably should have used something else (even if this code is more of
a one-off than anything else).

Anyhow, thanks.
 
S

Scott David Daniels

I'm a bit baffled. Here is a bit of fairly straightforward code:

def _chunkify( l, chunkSize, _curList = list() ): ...
_chunkify simply breaks a sequence into a sequence of smaller lists of
size <= chunkSize. The first call works fine, but if I call it
multiple times, weirdness happens.

Considering the default value of _curList, these statements should be
identical. Any pointers? Did I miss something in the python reference
manual? (running 2.4.3, fyi)

You've already got the real answer. How about considering iterators,
since I presume you are chunking to help some kind of processing.:

def chunky(src, size):
'''Produce a (possibly long source) in size-chunks or less.'''
assert size > 0
for start in range(0, len(src), size):
yield src[start : start + size]

def chunkify(alist, size, _curList=None):
if _curList is None:
return list(chunky(alist, size))
_curList.extend(list(chunky(alist, size)))
return _curList

I suspect most often you can use chunky directly:
for chunk in chunky(somedata, size):
...

for size in range(1, 30):
print size, list(chunky('abcdefghijklmnopqrstuvwxyz', size))


--Scott David Daniels
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top