I am a complete newbie in python.
I start doing lambda functions and they end up a bit longer than my initial goal:
Can I split it in different lines for better readability?, like this:
parts.map(lambda p: (p[0]\
,p[1]\
,int(p[1].split("-")[0])\
,int(p[1].split("-")[1])\
,p[2]\
,float(p[3])\
,p[4]))
or it defeats the purpose of using a lambda function?
I feel when I write it is ok to use lambda function in one line, is quick and good, but when I check again my code later I feel is not legible all of it in one line...
If it's not clearly readable as a simple one-liner, then it's not a good candidate for a lambda. Remember that the lambda statement is just syntactic sugar, technically it IS a function:
>>> def foo(): pass
...
>>> bar = lambda: None
>>>
>>> type(foo)
<class 'function'>
>>> type(bar)
<class 'function'>
>>>
So yes, in your example it does definitly "defeat the purpose of using a lambda function". As far as I'm concerned, if I had to maintain this code, I'd rather find something like:
def prepare(p):
p1a, p1b = (int(x) for x in p[1].split("-"))
p3f = float(p3)
return p[0], p[1], p1a, p1b, p[2], p3f, p[4]
whatever = [prepare(part) for part in parts]
If you are interested in style and readability I can't recommend the PEP8 style guide enough. Overall, it explains the best practices to write readable Python.
It will in particular give you advice on where to put commas when you start a new line, when to use parenthesis and how and when to write to a new line.
On lambda functions in particular it states:
Always use a def statement instead of an assignment statement that
binds a lambda expression directly to an identifier.
Yes:
def f(x): return 2*x
No:
f = lambda x: 2*x
In your case, I would use a function instead.
You could define a normal function and just use it in the map function if it gets too long.
def foo(p):
'''your code'''
result = list(map(foo, your_list)) # the list wrapper to convert map object to a list
Related
I am trying out lambda in python and came across this question:
def foo(y):
return lambda x: x(x(y))
def bar(x):
return lambda y: x(y)
print((bar)(bar)(foo)(2)(lambda x:x+1))
can someone explain/breakdown how this code works? I am having problems trying to figure out what is x and y.
Lambda functions are just functions. They're almost syntatic sugar, as you can think of this structure:
anony_mouse = lambda x: x # don't actually assign lambdas
as equivalent to this structure:
def anony_mouse(x):
return x
(Almost, as there is no other way of getting a function without assigning it to some variable, and the syntax prevents you doing some things with them, such as using multiple lines.)
Thus let's write out the top example using standard function notation:
def foo(y):
# note that y exists here
def baz(x):
return x(x(y))
return baz
So we have a factory function, which generates a function which... expects to be called with a function (x), and returns x(x(arg_to_factory_function)). Consider:
>>> def add_six(x):
return x + 6
>>> bazzer = foo(3)
>>> bazzer(add_six) # add_six(add_six(3)) = 6+(6+3)
I could go on, but does that make it clearer?
Incidentally that code is horrible, and almost makes me agree with Guido that lambdas are bad.
The 1st ‘(bar)’ is equal to just ‘bar’ so it is an ordinary function call, the 2nd — argument to that call, i.e. bar(bar) — substitute ‘x’ to ‘bar’ there any you will get what is result of bar(bar); the’(foo)’ argument passing to the result of bar(bar) it will be a lambda-function with some arg. — substitute it to ‘foo’ and get result and so on until you reach the end of expression
I slightly modify your original function to make clearer what's going on (so it should be clearer which parameter is callable!)
# given a function it evaluates it at value p
def eval(func): # your foo
return lambda p: func(p)
# given a value p perform a double composition of the function at this value (2-step recursion)
def iter_2(p): # your bar
return lambda func: func(func(p))
increment = lambda x: x + 1 # variable binding only for readability
This example is quite hard to understand because one of the function, eval just do nothing special, and it composition is equivalent to the identity! ... so it could be quite confusing.
(foo)(2)(lambda x:x+1)):
x = 2
iter_2(x)(increment) # increment by 2 because iter_2 calls increment twice
# 4
idempotency: (or composition with itself return the identity function)
increment(3) == eval(increment)(3)
# True
# idempotency - second composition is equivalent to the identity
eval(increment)(3) == eval(eval)(increment)(3)
# True
eval(increment)(3) == eval(eval)(eval)(increment)(3)
# True
# ... and so on
final: consequence of idempotency -> bar do nothing, just confusion
eval(eval)(iter_2)(x)(increment) == iter_2(x)(increment)
# True
Remark:
in (bar)(bar)(foo)(2)(lambda x:x+1) you can omit the brackets around the 1st term, just bar(bar)(foo)(2)(lambda x:x+1)
Digression: [since you example is quite scaring]
Lambda functions are also known as anonymous function. Why this? Simply because that they don't need to be declared. They are designed to be single purpose, so you should "never" assign to a variable. The arise for example in the context of functional programming where the basic ingredients are... functions! They are used to modify the behavior of other functions (for example by decoration!). Your example it is just a standalone syntactical one... essentially a nonsense example which hides the truth "power" of the lambda functions. There is also a branch mathematics which based on them called lambda calculus.
Here a totally different example of application of the lambda functions, useful for decoration (but this is another story):
def action(func1):
return lambda func2: lambda p: func2(p, func1())
def save(path, content):
print(f'content saved to "{path}"')
def content():
return 'content' # i.e. from a file, url, ...
# call
action(content)(save)('./path')
# with each key-parameter would be
action(func1=content)(func2=save)(p='./path')
Output
content saved to "./path"
I got the following code:
g = lambda x: x+7
foo = lambda f: (lambda x: f(x+1)*2)
print( g(3), (foo(g))(3), (foo(foo(g))((3) )
Could I get an explanation on how (foo(foo(g))((3) works?
The first thing to remember is that lambdas are regular functions that:
Don't automatically have names
Can be used as expressions
Must consist of a single expression
Implicitly return the results of that expression
So you can always rewrite them as normal def functions with names if you're confused. For example, foo can become:
def foo(f):
def foo_inner(x):
return f(x + 1) * 2
return foo_inner
So calling foo with any function (f) returns a new function which takes a numeric type, adds one to it, calls f with the value, and doubles the result.
All the rest of it is just tracing the multiple layers of wrapping here, which I'll leave to you; this isn't an interesting problem in general. In real code that uses factory functions like this, the intent and behavior is generally much more clear (because it's being done for a purpose, rather than as a brainteaser).
I'm curious about the difference between lambda function and a regular function (defined with def) - in the python level. (I know what is the difference for programmers and when to use each one.)
>>> def a():
return 1
>>> b = lambda: 1
>>> a
<function a at 0x0000000004036F98>
>>> b
<function <lambda> at 0x0000000004031588>
As we can see - python knows that b is a lambda function and a is a regular function. why is that? what is the difference between them to python?
They are the same type so they are treated the same way:
>>> type(a)
<type 'function'>
>>> type(b)
<type 'function'>
Python also knows that b was defined as a lambda function and it sets that as function name:
>>> a.func_name
'a'
>>> b.func_name
'<lambda>'
In other words, it influences the name that the function will get but as far as Python is concerned, both are functions which means they can be mostly used in the same way. See mgilson's comment below for an important difference between functions and lambda functions regarding pickling.
The only difference is that (a) the body of a lambda can consist of only a single expression, the result of which is returned from the function created and (b) a lambda expression is an expression which evaluates to a function object, while a def statement has no value, and creates a function object and binds it to a name.
In all other material respects they result in identical objects - the same scope and capture rules apply. (Immaterial differences are that lambda-created functions have a default func_name of "<lambda>". This may affect operation in esoteric cases - e.g. attempts to pickle functions.).
Both lambda and def create the same kind of function – they have the same kind of metadata and capabilities. Their technical difference is syntactical:
A lambda is an expression producing a function.
A def is a statement producing a function.
This is everything that dictates how they can be used. Other apparent differences simply come from the information lambda/def can capture.
>>> def def_func(): pass
>>> lambda_func = lambda: None
>>> type(def_func) == type(lambda_func)
True
Usage: Expression vs. Statement
A lambda is more flexible as expressions can be part of more language constructs.
# v--------------v arguments must be expressions
sort(values, key=lambda x: abs(x))
In contrast, a def is more powerful as it can consist of more language constructs.
def encode(num, base):
while num: # statements must be inside statements
num, bit = divmod(num, base)
yield bit
These differences derive directly from one being an expression and the other being a statement. Python has no special rules to decide where a lambda/def may be used.
Where the wild <lambda>s grow
The primary reason to assume lambda and def correspond to different kinds of function is metadata: lambda is often referred to as an "anonymous function" and miraculously it always produces a function <lambda>. Other quirks include "lambda functions can't be pickled", and recently typing also does "not work" for lambda.
That is because compared to def syntax, the lambda syntax has no way of specifying name, type annotations and similar. As such, Python simply fills in sane defaults for either: the name becomes <lambda> and annotations are left empty.
>>> identity = lambda a: a
>>> identity.__qualname__
'<lambda>'
>>> identity.__annotations__
{}
Since <lambda> is not a valid identifier, everything using this metadata to find the function – most prominently pickle – fails.
However, that does not make the function an "anonymous function" type. The metadata can be patched up to insert what def would provide:
>>> identity.__qualname__ = identity.__name__ = 'identity'
>>> identity
<function __main__.identity(a)>
Of course at that one point one can just use def…
First consider the diff b/w the two.
Lambda functions: are operator can have any number of arguments, but it can have only one expression. It cannot contain any statements and it returns a function object which can be assigned to any variable. They can be used in the block they were created.
def functions: Functions help break our program into smaller and modular chunks. As our program grows larger and larger, functions make it more organised and manageable. They can be called and used anywhere we want.
Here you can get more clear difference by following example.
Defining a function
def add(a,b):
return a+b
print(add(4,5))
Defining a lambda
add = lambda x, y : x + y
print(add(4,5))
Lambda is an inline function where we can do any functionality without a function name.
It is helpful when we use it as an argument to a higher-order function.
Eg: A function that takes in other functions as arguments.
Example of Function definition:
>>> def func(a, b):
return a * b
>>> func(2,3)
6
>>> type(func)
<class 'function'>
>>> func
<function func at 0x034B6E88>
Example of Lambda expression:
>>> multiply = lambda a, b: a * b
>>> multiply(2, 3)
6
>>> type(multiply)
<class 'function'>
>>> multiply
<function <lambda> at 0x034B6ED0>
Both returns same output value. Only object returned are different. "func" name for Function and for Lambda.
lambda creates an anonymous function. This idea has been taken from functional programming languages. In this way you can create and pass the function to other functions like map and filter. (look here)
You can pass normal functions to these functions too, but since mostly they are simple and they are not used anywhere else, it's inconvenient to go through the whole process of definfing a new function.
As an example take a look at this:
>>> a = [1, 2, 3, 4]
>>> print map( lambda x : x*2 + 1, a )
[3, 5, 7, 9, 11]
I want to write a simple function that recognizes palindromes:
>>> def palindrome(s):
return s == s[::-1]
It works fine but it is case sensitive and to fix that I could do:
>>> def palindrome(s):
return s.lower() == s[::-1].lower()
>>> palindrome('Aba')
True
but I figure it's not very elegant. I tried to lowercase the input by using lambda expressions but I am doing something wrong and don't know how to fix it:
>>> def palindrome(lambda s : s.lower()):
return s == s[::-1]
SyntaxError: invalid syntax
You cannot use a lambda expression to describe actions that should be performed on input parameters (you can however use lambda to define a default value). You can do two things:
Define a function in the head of the function:
def palindrome(s):
s = s.lower()
return s == s[::-1]
Use a decorator:
def caseinsensitive(f):
def helper(s):
s = s.lower()
return f(s)
return helper
and then define your palindrome as:
#caseinsensitive
def palindrome(s):
return s == s[::-1]
Here you can reuse the #caseinsensitive to define all functions that do this as a first step.
Just call lower once, reassign s to the value and forget the lambda:
def palindrome(s):
s = s.lower()
return s == s[::-1]
This isn't really idiomatic python, but what you're looking for is something like this:
def palindrome(s):
return (lambda x: x == x[::-1])(s.lower())
That is, you define a lambda function and immediately invoke it, binding s.lower() to x.
def palindrome(s):
s = s.lower()
return s == s[::-1]
This is pretty straightforward and easy to use and understand answer, which is 100% correct and good.
BUT if you want to use lambda expression you must think how and what and why and stuff so let's go into the magical world of FUNCTIONAL PROGRAMMING.
If you don't know what a lambda expression is, basically when you type in the word lambda it specifies that you will later on give it some value for instance typing lambda a means you will supply it with 1 value (argument), typing lambda a, b explicitly means you will suppliy it with 2 values (arguments). So now that this whole thing of "what does even this lambda word mean" is done let's go deeper into the magical world of FUNCTIONAL PROGRAMMING.
So now when you tell python that it will have to wait some time (or maybe no time at all) for that value so it can do some magic on it, you can tell it what to do with it for instance
some_var = lambda some_string: some_string.lower()
So now this means that it's going to get some value, we expect it to be some sort of string and we can and will hold it in some_var for reasons only PHP programmers and us (me) know.
Next up is really straight forward we just return the check whether it is or not a palindrome
return some_var == some_var[::-1]
Let's get some glue and build this lambda beast from the things we have earlier
def palindrome():
some_var = lambda some_string : some_string.lower()
return some_var == some_var[::-1]
As you can see we no longer need to declare that we use some puny s in the method, hence we just press DEL and we can go along into the beatiful world of FUNCTIONAL PROGRAMMING.
So let's try to call this function, but the question raises how to do it?
palindrome("superpalindrome") == False
It does not compile though, because it thinks we are trying to give the palindrome method some kind of an argument while the definition has none at all. So the correct call of the function should be
palindrome()("superpalindrome") == False
In short, this is just magic, lambda expressions are actually in most cases worse in case of time usage, so you should stick to doing stuff in a OOP way or even else pythonic way. If you want to use lambda expressions you should try switching to Haskell(which I strongly advise) or Scala. If you have any further questions, feel free to ask me, I love talking about Haskell. Or FUNCTIONAL PROGRAMMING.
Full answer that is even more simplified
def palindrome():
return lambda some_str : some_str.lower() == some_str.lower()[::-1]
method = palindrome()
print(method("cococ"))
Maybe you wanted this:
(lambda lstr : lstr == lstr[::-1])((lambda x : x.lower())('abA'))
I usually use the following pattern (as mentioned in this question):
a=1
s= "{a}".format(**locals())
I think it's a great way to write easily readable code.
Sometimes it's useful to "chain" string formats, in order to "modularize" the creation of complex strings:
a="1"
b="2"
c="{a}+{b}".format(**locals())
d="{c} is a sum".format(**locals())
#d=="1+2 is a sum"
Pretty soon, the code is pestered with X.format(**locals()).
To solve this problem, I tried to create a lambda:
f= lambda x: x.format(**locals())
a="1"
b="2"
c= f("{a}+{b}")
d= f("{c} is a sum")
but this throws a KeyError, since locals() are the lambda's locals.
I also tried to apply the format only on the last string:
a="1"
b="2"
c="{a}+{b}"
d="{c} is a sum".format(**locals())
#d=="{a}+{b} is a sum"
But this doesn't work, since python only formats once.
Now, I could write a function that formats repeatedly until there's nothing more to do:
def my_format( string, vars ):
f= string.format(**vars)
return f if f==string else my_format(f, vars)
but I'm wondering: is there a better way to do this?
f = lambda x, l=locals(): x.format(**l) appears to work...
and if you wanted a version that is a little more all-encompassing (and probably a lot slower):
fg = lambda x, l=locals(), g=globals(): x.format(**dict(g.items() + l.items()))
will find the symbols in either locals or globals.
If you only need to do this within the function scope as a local shortcut, the following will work:
def formatter(fmt, loc=locals()):
return fmt.format(**loc)
However, this will bind the value returned by locals() at the time of function declaration, rather than execution, so it will not be updated as values change, nor will it be useful when called from any other scope.
If you want to get access to the calling method's locals, you need to inspect the call stack (http://docs.python.org/2/library/inspect.html)
import inspect
def formatter(fmt):
parent = inspect.stack()[1][0] # 1 = the previous frame context
# 0 = the frame object
return fmt.format(**parent.f_locals)
Note that this may not work for implementations of python that are not CPython.
Now you can do:
a = "1"
b = "2"
c = formatter("{a}+{b}")
d = formatter("{c} is a sum")
Starting with Python 3.6 the effect of **locals() is already included in string#format or rather "formatted string literals".
See also PEP 498
and Python 3.6 release notes.
It's not a one-liner, but it works:
def fmt(s, l=locals()):
while '{' in s:
s = s.format(**l)
return s
a="1"
b="2"
c="{a}+{b}"
d="{c} is a sum"
print fmt(d) # 1+2 is a sum
Here's a one line (and slightly less efficient) recursive version:
fmt = lambda s, l=locals(): fmt(s.format(**l), l=l) if '{' in s else s