A faster method to generate a nested list from a template?
jasondrew72 at gmail.com
jasondrew72 at gmail.com
Wed May 4 12:27:37 EDT 2005
Jeff Epler wrote:
> Are there only a few, unchanging templates? If so, (dynamiclly)
create
> a function for each template. This will be nearly the fastest you
can
> go in Python, excluding the time to create and byte-compile the
nesting
> function.
>
> # This code is in the public domain
> def make_nesting_expression(l, s):
> result = []
> for c in l:
> if isinstance(c, list):
> sub, s = make_nesting_expression(c, s)
> result.append(sub)
> else:
> result.append("l[%d]" % s)
> s += 1
> print "make_nesting_expression", l, result
> return "[" + ",".join(result) + "]", s
>
> def make_nesting_function(l):
> return eval("lambda l: %s" % make_nesting_expression(l, 0)[0])
>
> t = [['a1','a2'],['b1'],['c1'],['d1']]
> l = [1, 2, 3, 4, 5]
> f = make_nesting_function(t)
> print f(l)
>
> Jeff
Nice approach! Though I'm wondering, because the "template" is so close
to the function you're trying to create, why not just create the
function directly? As in:
>>> f5 = lambda p: (p[0:2], p[2], p[3], p[4])
>>> f5(('a', 'b', 'c', 'd', 'e', 'f'))
(('a', 'b'), 'c', 'd', 'e')
Or if you need to be able to remember what the template looks like
(e.g. reading/writing it as a string in a file), you can always create
the function by evaluating a (properly constructed) template string:
>>> f5 = eval("lambda p: (p[0:2], p[2], p[3], p[4])")
>>> f5(('a', 'b', 'c', 'd', 'e', 'f'))
(('a', 'b'), 'c', 'd', 'e')
If you want to avoid lambdas, the same ideas can be used with short
defs, e.g.:
def f5(p): return (p[0:2], p[2], p[3], p[4])
Incidentally, these solutions raise an IndexError if your list is too
short, and silently drop the end of a list that's too long.
That's my keep-it-simple-I-might-understand-it approach.
Jason
More information about the Python-list
mailing list