Lambda question
Terry Reedy
tjreedy at udel.edu
Mon Jun 6 12:52:31 EDT 2011
More information about the Python-list mailing list
Mon Jun 6 12:52:31 EDT 2011
- Previous message (by thread): Lambda question
- Next message (by thread): Lambda question
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 6/6/2011 9:42 AM, jyoung79 at kc.rr.com wrote: >>>>>> f = lambda x, n, acc=[]: f(x[n:], n, acc+[(x[:n])]) if x else acc > >> Packing tail recursion into one line is bad for both understanding and >> refactoring. Use better names and a docstring gives >> >> def group(seq, n): >> 'Yield from seq successive disjoint slices of length n plus the >> remainder' >> for i in range(0,len(seq), n): >> yield seq[i:i+n] [I added back the last 'n' that got deleted somehow] > Thank you all very much for this incredible help! The original code > now makes sense, and I was thrilled to see better and more efficient > ways of doing this. Thanks for taking the time to share your > thoughts as well as the excellent detail everyone shared… I really > appreciate it! You are welcome. Let me add something not said much here about designing functions: start with both a clear and succinct definition *and* test cases. (I only started writing tests first a year ago or so.) Test cases help test the definition statement as well as the yet-to-be-written code. They also make re-factoring much safer. I think test cases should start with null inputs. For this function: for inn,out in ( (('',1), []), # no input, no output (('abc',0), []), # definition unclear, could be error (('abc',1), ['a','b','c']), (('abcd',2), ['ab','cd']), (('abcde',2), ['ab', 'cd', 'e']), # could change this ): assert list(group(*inn)) == out, (inn,out) This fails with ValueError: range() arg 3 must not be zero I will let you think about and try out what the original code 'f=../ does with n=0. It is not good. A third problem with lambda expressions is no test for bad inputs. They were added to Python for situations where one needs a function as an argument and and the return expression is self-explanatory, clearly correct, and safe for any inputs it could get in the context it is passed into. For example, lambda x: 2*x. This works: def group(seq, n): 'Yield from seq successive disjoint slices of length n & the remainder' if n<=0: raise ValueError('group size must be positive') for i in range(0,len(seq), n): yield seq[i:i+n] for inn,out in ( (('',1), []), # no input, no output #(('abc',0), ValueError), # group size positive (('abc',1), ['a','b','c']), (('abcd',2), ['ab','cd']), (('abcde',2), ['ab', 'cd', 'e']), # could change this ): assert list(group(*inn)) == out, (inn,out) I have written a function test function that I will post or upload to PyPI sometime. It accepts i/o pairs with error 'outputs', like the one commented out above. -- Terry Jan Reedy
- Previous message (by thread): Lambda question
- Next message (by thread): Lambda question
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list