I'm reading a python script with the module Theano used. I'm confused by the follow piece of code.
import numpy as np
import theano.tensor as T
lparam = T.dvector('lparam') # packed parameters
func = lambda expr: (theano.function([lparam],expr),expr)
i = [0]
def read_param(size):
ret = lparam[i[0]:i[0]+size]
i[0] += size
return ret
The function read_param is used in functions beneath.
N = 20
unpack_param, unpack_param_expr = func(T.stack(
read_param(N), # sigmoid energy
read_param(N), # sigmoid switching z
T.exp(read_param(N)), # sigmoid scale (>0)
read_param(N), # gaussian energy
read_param(N), # gaussian location
T.exp(read_param(N)))) # gaussian scale (1/2sigma**2)
def pack_param(param):
return np.concatenate((
param[0],
param[1],
np.log(param[2]),
param[3],
param[4],
np.log(param[5])), axis=0)
I was told that it uses the concept of "closure" and is advantageous in writing and reading. But I'm not sure why and how it works.
My only guess is that the author didn't want to define
i
as a global variable:I don't know why (maybe the author doesn't know Python well).
There is no advantage in using
i[0]
, only disadvantages -- bad readibility and more CPU used.The trick here is that
i
is a mutable object --list
and you mutate it instead of reassigning (which would require to define it asglobal
). I would use a more pythonic approach like in @Marius's answer.I think the author considers this a cool trick (though this one is cooler:
def read_param(size, i=[0]):
) and will defend his approach, but The Zen of Python should be followed: