I asked for assistance creating a Python Lambda function capable of assignments and multi-line lambdas in this post. Following @l0b0's suggestions, I realized that it was better constructed as a class.
There is a security risk associated with eval or exec and input strings as well as an increased difficulty debugging code but I wanted a more capable lambda for functional experiments. This is probably unsuitable for production code.
Print will provide a code string that can be executed if you add the arguments.
Any suggestions for further improvements would be appreciated.
class lambda_(): """ Creates an executable anonymous function supporting multiple line and assignments. For one line the form is λ("parameters : code incl assignment")(*arguments) and the first exepression is assigned to rtrn which is returned For multiline, use triple quotes with the parameters on the first line, the : is followed directly by a line feed and then the code Input: code in the form "x, y,...: return_value_expression; other code" Output is assigned to variable rtrn """ def __init__(self, code): """ self.parameters parses parameters (preceding the colon) self.code is the code after the colon with extra leading spaces removed from multiline lambdas """ self.parameters =  val_idx = 0 val_name =  i = 0 if ":" in code: for i, c in enumerate(code): # loop until the : that ends parameters if c in ",:": if val_name: self.parameters.append(''.join(val_name)) val_name =  val_idx += 1 if c == ":": break elif c != " ": val_name.append(c) # self.code sets rtrn = None for multiline or sets rtrn = first expression for # single line unless :: (used if first expression can't be evaluated) if code[i+1] != "\n": # single line, if code[i+1] != ":": if code[i] != ":": self.code = ''.join(("rtrn = ", code)) else: self.code = ''.join(("rtrn = ", code[i+1:])) else: self.code = ''.join(("rtrn = None; ", code[i+2:])) else: # multiline # wont run if excess leading spaces so remove them lead = 0 code_ = code[i+1:] while code_[lead+1] == " ": # how many on 1st line? lead += 1 for i in range(1, len(code_)): # remove that on all lines if code_[i-1: i+1] == "\n ": code_ = code_[: i] + code_[i+lead:] self.code = "rtrn = None" + "\n" + code_ # executable code def __call__(self, *args): """ All arguments are declared global as listcomps etc don't create closure when called using exec, so first declare parameters & rtrn as globals, then collect parameter=value pairs in assignments. Multiline will return None unless you assign rtrn a value. """ define_globals = ', '.join(["global rtrn"] + self.parameters) assign = '; '.join([' = '.join((p, str(args[i]))) for i, p in enumerate(self.parameters)]) exec('; '.join((define_globals, assign if assign else "pass", self.code))) return rtrn def __str__(self): args = ["??" for _ in self.parameters] define_globals = ', '.join(["global rtrn"] + self.parameters) assign = '; '.join([' = '.join((p, str(args[i]))) for i, p in enumerate(self.parameters)]) return '; '.join((define_globals, assign if assign else "pass", self.code)) λ = lambda_ # rebind to linux ctrl+shift+u 03BB
print( λ("""var: for i in range(var): print(i, end = ",") print(' ', end='') if i == var - 1: print(var) print(var) rtrn = [i for i in range(var, 0, -1)] """)(5) ) print(λ("x: [x*i for i in range(x)]; print('Final:', rtrn[-1])")(3)) print(λ("x, y:: from math import cos, sin; rtrn = cos(x) + sin(y)")(3, 5)) def applyToEach(L, f): for i in range(len(L)): L[i] = f(L[i]) testList = [1, -4, 8, -9] apply_to_each(testList, λ("x: x if x >= 0 else -x")) print(testList, "\n") multiline = λ("""var: for i in range(var): print(i, end = ",") print(' ', end='') if i == var - 1: print(var) print(var) rtrn = [i for i in range(var, 0, -1)] """) print("Multiline lambda") ; print(multiline) p_lambda = λ('print("value")') print("parameterless lambda") ; print(p_lambda)