def fred(cf,toplevel=True):
x = cf[0]
if len(cf)>1:
if toplevel:
return x + fred(cf[1:],False)
else:
return "(" + x + fred(cf[1:],False) + ")"
else:
if toplevel:
return x
else:
return "(" + x + ")"
about the case where you want to handle something differently
in the top level than in lower levels? Is there any way to tell
from within a function that it wasn't invoked by itself?
I've come up with a hack to support different processing, by
use of an extra argument
def fred(cf,toplevel=True):
Aside from being ugly, this lets the caller diddle with "toplevel",
which shouldn't really be externally modifiable.
Are there better ways to do this?
--
Michael F. Stemper
I refuse to believe that a corporation is a person until Texas executes one.
def rest( s ):
return "(" + s[ 0 ] +( rest( s[1:] ) if len( s )> 1 else '' )+ ')'
def nest( s ):
return( s[ 0 ] if s else '' )+( rest( s[1:] )if len( s )> 1 else '' )
On Tuesday, 13 December 2022 at 15:46:49 UTC+1, Michael F. Stemper wrote:
about the case where you want to handle something differently
in the top level than in lower levels? Is there any way to tell
from within a function that it wasn't invoked by itself?
I've come up with a hack to support different processing, by
use of an extra argument
def fred(cf,toplevel=True):
To make it slightly more general pass the level number,
then it's quite a common scheme.
Aside from being ugly, this lets the caller diddle with "toplevel",
which shouldn't really be externally modifiable.
That's a different issue, that Python is "strictly dynamic"
(there is no such thing as constants or private scope):
which one can "mitigate", courtesy supporting tools,
by decorating constructs with type annotations.
Are there better ways to do this?
--
Michael F. Stemper
I refuse to believe that a corporation is a person until Texas executes one.
def rest( s ):
return '(' + nest( s )+ ')'
def nest( s ):
return s[ :1 ]+( rest( s[ 1: ])if s[ 1: ]else '' )
On Wed, 14 Dec 2022 at 03:35, Michael F. Stemper
<michael.stemper@gmail.com> wrote:
It's easy enough -- in fact necessary -- to handle the bottom
level of a function differently than the levels above it. What
about the case where you want to handle something differently
in the top level than in lower levels? Is there any way to tell
from within a function that it wasn't invoked by itself?
Why does it have to be the same function?
def _sort_recursive(stuff, keys, start, end):
"""imagine a nice implementation of some sorting algorithm here"""
def sort(stuff, key=None):
if key:
keys = [key(x) for x in stuff]
else:
keys = stuff
return _sort_recursive(stuff, 0, len(stuff))
On 12/13/22 10:36, Chris Angelico wrote:
On Wed, 14 Dec 2022 at 03:35, Michael F. Stemper <michael.stemper@gmail.com> wrote:
It's easy enough -- in fact necessary -- to handle the bottom
level of a function differently than the levels above it. What
about the case where you want to handle something differently
in the top level than in lower levels? Is there any way to tell
from within a function that it wasn't invoked by itself?
Why does it have to be the same function?
def _sort_recursive(stuff, keys, start, end):
"""imagine a nice implementation of some sorting algorithm here"""
def sort(stuff, key=None):
if key:
keys = [key(x) for x in stuff]
else:
keys = stuff
return _sort_recursive(stuff, 0, len(stuff))
if some support for this position is needed, this is roughly how the
stdlib glob() function is implemented.
It's easy enough -- in fact necessary -- to handle the bottom
level of a function differently than the levels above it. What
about the case where you want to handle something differently
in the top level than in lower levels? Is there any way to tell
from within a function that it wasn't invoked by itself?
"Michael F. Stemper" <michael.stemper@gmail.com> writes:
def fred(cf,toplevel=True):
x = cf[0]
if len(cf)>1:
if toplevel:
return x + fred(cf[1:],False)
else:
return "(" + x + fred(cf[1:],False) + ")"
else:
if toplevel:
return x
else:
return "(" + x + ")"
def rest( s ):
return "(" + s[ 0 ] +( rest( s[1:] ) if len( s )> 1 else '' )+ ')'
def nest( s ):
return( s[ 0 ] if s else '' )+( rest( s[1:] )if len( s )> 1 else '' )
On Wed, 14 Dec 2022 at 03:35, Michael F. Stemper
<michael...@gmail.com> wrote:
It's easy enough -- in fact necessary -- to handle the bottom
level of a function differently than the levels above it. What
about the case where you want to handle something differently
in the top level than in lower levels? Is there any way to tell
from within a function that it wasn't invoked by itself?
Why does it have to be the same function?
def _sort_recursive(stuff, keys, start, end):
"""imagine a nice implementation of some sorting algorithm here"""
def sort(stuff, key=None):
if key:
keys = [key(x) for x in stuff]
else:
keys = stuff
return _sort_recursive(stuff, 0, len(stuff))
With purely recursive functions (where every call to the function
truly could have been a top-level call - a lot of mathematical
functions work out this way), it makes sense to call the
externally-callable function recursively; but for anything more messy,
it's usually easiest to make the recursive part internal, and then
have a top-level function that calls into the recursive one.
On 13/12/2022 09.03, Stefan Ram wrote:
"Michael F. Stemper" <michael...@gmail.com> writes:
def fred(cf,toplevel=True):
x = cf[0]
if len(cf)>1:
if toplevel:
return x + fred(cf[1:],False)
else:
return "(" + x + fred(cf[1:],False) + ")"
else:
if toplevel:
return x
else:
return "(" + x + ")"
def rest( s ):
return "(" + s[ 0 ] +( rest( s[1:] ) if len( s )> 1 else '' )+ ')'
def nest( s ):
return( s[ 0 ] if s else '' )+( rest( s[1:] )if len( s )> 1 else '' )
Hey, that's slick! And if I define rest within nest, it's not going
to be externally accessible.
Hey, that's slick! And if I define rest within nest, it's not going
to be externally accessible.
It's easy enough -- in fact necessary -- to handle the bottom
level of a function differently than the levels above it. What
about the case where you want to handle something differently
in the top level than in lower levels? Is there any way to tell
from within a function that it wasn't invoked by itself?
I've come up with a hack to support different processing, by
use of an extra argument, as shown in this simplified example:
def fred(cf,toplevel=True):
x = cf[0]
if len(cf)>1:
if toplevel:
return x + fred(cf[1:],False)
else:
return "(" + x + fred(cf[1:],False) + ")"
else:
if toplevel:
return x
else:
return "(" + x + ")"
Aside from being ugly, this lets the caller diddle with "toplevel",
which shouldn't really be externally modifiable.
Are there better ways to do this?
return reduce(lambda x, y: func(y, x), items[::-1])from functools import reduce
def foldr(func, items):
'1(2(3(4)))'foldr("{0}({1})".format, [1,2,3,4])
On 13/12/2022 15:46, Michael F. Stemper wrote:
I've come up with a hack to support different processing, by
use of an extra argument, as shown in this simplified example:
def fred(cf,toplevel=True):
x = cf[0]
if len(cf)>1:
if toplevel:
return x + fred(cf[1:],False)
else:
return "(" + x + fred(cf[1:],False) + ")"
else:
if toplevel:
return x
else:
return "(" + x + ")"
Aside from being ugly, this lets the caller diddle with "toplevel",
which shouldn't really be externally modifiable.
Are there better ways to do this?
For adepts of functional programming the above is a "fold right"
operation, first hit for "foldr in python":
https://burgaud.com/foldl-foldr-python
With that
from functools import reduce
def foldr(func, items):
return reduce(lambda x, y: func(y, x), items[::-1])
I also found an example similar to what was discussed here
in pypy's library file "...\Lib\_tkinter\__init__.py":
|def _flatten(item):
| def _flatten1(output, item, depth):
| if depth > 1000:
| raise ValueError("nesting too deep in _flatten")
| if not isinstance(item, (list, tuple)):
| raise TypeError("argument must be sequence")
| # copy items to output tuple
| for o in item:
| if isinstance(o, (list, tuple)):
| _flatten1(output, o, depth + 1)
| elif o is not None:
| output.append(o)
|
| result = []
| _flatten1(result, item, 0)
| return tuple(result)
.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 446 |
Nodes: | 16 (2 / 14) |
Uptime: | 19:34:36 |
Calls: | 9,234 |
Calls today: | 1 |
Files: | 13,496 |
Messages: | 6,063,226 |