March 22, 2005
Lambda revisited

There's me saying that I'd be happy to see the back of lambda, and the effbot goes and posts ElementPlist, a beautiful use for them. Nothing there you couldn't do without lambda, but not so elegantly.

He only does it to make me look stupid, you know. ;-)

Posted to Python by Simon Brunning at March 22, 2005 02:06 PM
Comments

On that front, what's the approved-but-concise way of doing map(None, l1, l2, ...) these days?

Posted by: The Badger on March 22, 2005 03:01 PM

zip{l1, l2, ...)

Not *exactly* the same - map(None...) pads the shorter sequences with NONE, zip() truncates to the length of the shortest list. But then I only ever seem to need to zip sequences that have the same lengths anyway.

Posted by: Simon Brunning on March 22, 2005 03:12 PM

Footnote: If you want a lambda-free solution, you can trivially change the dictionary to:

class unmarshallers:
  def array(s,x): return [v.text for v in x]
  def dict(s,x): return dict((x[i].text or "", x[i+1].text) for i in range(0, len(x), 2))
  def key(s,x): return x.text or ""
  def string(s,x): return x.text or ""
  def data(s,x): return base64.decodestring(x.text)
  def date(s,x): return datetime.datetime(*map(int, re.findall("\d+", x.text)))
  def true(s,x): return True
  def false(s,x): return False
  def real(s,x): return float(x.text)
  def integer(s,x): return int(x.text)
unmarshallers = unmarshallers()

and replace the unmarshallers.get line with:

unmarshal = getattr(unmarshallers, elem.tag, None)

and you're done. Pretty elegant, if you're asking me.

(you can also do this without a class, using a custom decorator to populate the dispatch table. some pythonheads will think that such a solution is even more elegant. ymmv)

(and btw, the reason I'm not using this in my code is that the dictionary version also handles namespaces, which is a good thing if you want to reuse the pattern for e.g. SOAP decoding...)

Posted by: Fredrik on March 22, 2005 07:12 PM

OK, I should have said that *I* couldn't do it so elegantly without lambda. ;-)

Posted by: Simon Brunning on March 23, 2005 11:00 AM

Why didn't you use def's in the first place Fredrik? Old habit or deliberately?

Posted by: Peter Bengtsson on March 24, 2005 08:56 AM

Simon, I'm only doing this to make you look stupid, you know ;-)

Peter, see the last line in my post ("the reason I'm not using this"). (in addition, the getattr solution is slower, since it has to create bound methods for each item. you can avoid that by using unbound methods instead, but then the calling code gets harder to understand. I always prefer fast, readable, and scalable solutions over fancy tricks.)

Posted by: Fredrik on March 24, 2005 09:09 AM

Simon, here's a phone number formatter I wrote, which uses lamda and map(). Based on your earlier comments about lamda, I was wondering if you had a better way to write this function or if it was another case of good use of lamda ;) :

def FormatPhone(num):
base = []
ext = []
root = []
full = []
phone = num.split('x')
if len(phone) == 1:
phone = num.split('e')
x = 0
for frag in phone:
x += 1
for char in frag:
try:
digit = int(char)
except:
pass
else:
if x == 1:
base.append(digit)
else:
ext.append(digit)
if len(base) == 10:
root.append(''.join(map(lambda x: str(x), base[:3])))
root.append(''.join(map(lambda x: str(x), base[3:6])))
root.append(''.join(map(lambda x: str(x), base[6:])))
else:
root.append(''.join(map(lambda x: str(x), base[:3])))
root.append(''.join(map(lambda x: str(x), base[3:])))
full.append('-'.join(root))
if ext:
full.append(''.join(map(lambda x: str(x), ext)))
return ' ext '.join(full)

if __name__ == '__main__':
numbers = ['(254)752-6521','254-752-6521','254.752.6521','2547526521','752-6521','7526521','752.6521',\
'(254)752-6521x121','254-752-6521e121','254.752.6521ext121','2547526521 ext 121','752-6521 x 121',\
'7526521 e 127']
for num in numbers:
print FormatPhone(num)

Posted by: Lewis on March 24, 2005 10:08 PM

Well, I come in the office this Monday morning to talk with my co-worker who just returned from PyCon and he suggested I use:

root.append(''.join(str(x) for x in base[:3]))

A good use of the generator in Python 2.4

Posted by: Lewis on March 28, 2005 03:41 PM
Post a comment
Name:


Email Address:


URL:



Comments:


Remember info?