Package: on-the-lam
OnthelamTired of painstakingly writing the characterslambda:every time you want a
simple lambda function?Onthelamis the package for you.>>>fromonthelamimport_>>>mapping=dict(foo=2,bar=1,baz=3)>>>sorted_by_value=sorted(mapping.items(),key=_[1])>>>sorted_by_value[('bar',1),('foo',2),('baz',3)]Sure, youcouldtypelambda pair: pair[1], but doesn't_[1]feel so much
nicer? I think it does.Onthelam supports painless definition of lambda functions that use any
combination of comparators, arithmetic operations, bitwise operations,
indexing, and attribute getting.Installation and RequirementsOnthelam is installable from PyPI:$pipinstallon-the-lamThis initial release is only tested with and supports Python 3.9, but future
releases will aim at supporting older Python versions as well.Onthelam is written in pure Python and brings in no additional dependencies.Readable reprOnthelam lambdas provide a user-friendlyreprstring for easier debugging.>>>fn=-(_.count%5+42)**3>>>fn_->-(_.count%5+42)**3Can your native lambdas do that?This is especially useful for logging errors in functions that accept functions
as arguments, enabling you to log something about the argument that isn't just<function <lambda>(x)>.ComposableNeed to use the same argument twice in your lambda? No sweat.>>>tetration_2=_**_>>>tetration_2(5)3125Need a lambda with more than one argument? Combining lambda builders with
different names gets you a function that takes as many arguments as you have
distinct names. There are ten additional numbered lambda builders importable
from the main onthelam module. Specify the order of your arguments by the order
of their names.>>>fromonthelamimport_1,_2,_3>>>fn=_2[_1]+_3You still get a usefulrepr:>>>fn_1,_2,_3->_2[_1]+_3And it works like you'd expect it:>>>fn(2,[1,2,3],4)7RenamableMaybe you take umbrage with my aesthetic choice to use an underscore as my
lambda identifier. That's fine. Rename it all you want:>>>fromonthelamimportLambdaBuilder>>>λx=LambdaBuilder("λx")>>>[*map(λx//2,range(10)][0,0,1,1,2,2,3,3,4,4]It uses whatever name you give it in itsrepr:>>>λx//2λx->λx//2MagicSimplify your life further by taking advantage of the fact that onthelam
includes real, literal magic to grant a lambdabuilder by any name your heart
desires:>>>fromonthelam.magicimportλ_happy_lamb>>>λ_happy_lamb.baaλ_happy_lamb->happy_lamb.baaOr consider replacing the standard underscore with magic to allow yourself the
freedom to use ad-hoc argument names:>>>fromonthelamimportmagicas_>>>fn=_.mapping[_.key]>>>fnkey,mapping->mapping[key]Take advantage of this for functions you want to call by keyword:>>>fn(mapping={"hello":"world"},key="hello")'world'Designed with itertools in mindThe itertools module in the standard library is incredibly powerful, but using
it often results in ugly code where you have to decide whether to use inline
lambdas which add a lot of line noise or lots of one-time named function
definition blocks that take up a lot of space relative to their importance.Consider the following implementation of tetration, the mathematical operation
of iterated exponentiation of a number with itself.>>>fromfunctoolsimportreduce>>>fromitertoolsimportrepeat>>>deftetration(x,n):..."""Iterate `x ** x` n times"""...returnreduce(_1**_2,repeat(x,n))...>>>tetration(5,1)5>>>tetration(5,2)3125>>>tetration(5,3)298023223876953125Onthelam clears out the clutter from using lambdas.LimitationsOnthelam works by using the various special methods available to a class for
customizing the behavior of an instance when it is operated on. In short:
through lots of operator overloading. The limitation is that there are some
expressions involving aLambdaBuilderinstance that the object can't
seamlessly transform into a lambda function. As a result, they are interpreted
as attempts to use the defined lambda function as a lambda function. These are:Boolean contexts. Anything that tries to interpret the lambda argument's
truthiness will fail entirely. E.g., the expression1 if _ else 0will fail.Use as the index to an object that is not itself a lambda argument. E.g., the
expression[1, 2, 3][_]will fail.Tests of containment. E.g., the expression_ in [1, 2, 3]will fail.Using the lambda argument as an argument in a function call. E.g., the
expressionord(_)will call theordfunction with an identity lambda, not
create a lambda which callsordon its argument. Considerfunctools.partialfor this case.