2

I am trying to use lambda functions inside python dictionaries for a simple chemical properties database. This code

Psat = dict()
Psat['acetone'] = lambda T: 10**(7.02447 - 1161.0/(224 + T))
Psat['benzene'] = lambda T: 10**(6.89272 - 1203.531/(219.888 + T))
Psat['ethanol'] = lambda T: 10**(8.04494 - 1554.3/(222.65 + T))
Psat['toluene'] = lambda T: 10**(6.95805 - 1346.773/(219.693 + T))

K = dict()
for n in Psat.keys():
    K[n] = lambda P,T: Psat[n](T)/P

P = 760
T = 65

print "Pressure     {:6.2f} [mmHg]".format(P)
print "Temperature  {:6.2f} [deg C]".format(T)
print "K-factors:"
for n in K.keys():
    print "   {:s}  {:7.3f}".format(n,K[n](P,T))

works as I expected, returning

Pressure     760.00 [mmHg]
Temperature   65.00 [deg C]
K-factors:
   benzene    0.613
   acetone    1.338
   ethanol    0.576
   toluene    0.222

However, this code does not.

for n,k in K.iteritems():
    print k(P,T),K[n]

def test():
    for (n,k) in K.iteritems():
        print k(P,T),k

test()

In fact, these return different results.

0.612816477285 <function <lambda> at 0x1072de500>
1.33768965865 <function <lambda> at 0x1072de5f0>
0.57634791331 <function <lambda> at 0x1072de578>
0.222137215724 <function <lambda> at 0x1072de668>
0.222137215724 <function <lambda> at 0x1072de500>
0.222137215724 <function <lambda> at 0x1072de5f0>
0.222137215724 <function <lambda> at 0x1072de578>
0.222137215724 <function <lambda> at 0x1072de668>

I'm developing this on Python 2.7 in an IPython notebook using the Anaconda distribution. Any advice?

  • 2
    `n` in the `for n in Psat.keys():` loop is a closure name here, and looked up when you *call* the lambda, not when you define it. – Martijn Pieters Mar 24 '14 at 13:53
  • 1
    Note that you don't need to call `.keys()`; loop directly over dictionaries and save yourself a method call: `for n in Psat:`. – Martijn Pieters Mar 24 '14 at 13:54
  • Short answer: `K[n] = lambda P,T,n=n: Psat[n](T)/P` would fix your problem by binding `n` to a local name (via a default argument value). – Martijn Pieters Mar 24 '14 at 13:54
  • 1
    Don't name your variables `n`, `k` and `K`. Use names like `name`, `sat_func`, to make it clear to yourself what exactly you are doing. – Sjoerd Mar 24 '14 at 13:55

0 Answers0