Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm trying to figure out Python lambdas. Is lambda one of those "interesting" language items that in real life should be forgotten?
I'm sure there are some edge cases where it might be needed, but given the obscurity of it, the potential of it being redefined in future releases (my assumption based on the various definitions of it) and the reduced coding clarity - should it be avoided?
This reminds me of overflowing (buffer overflow) of C types - pointing to the top variable and overloading to set the other field values. It feels like sort of a techie showmanship but maintenance coder nightmare.
Are you talking about lambda expressions? Like
lambda x: x**2 + 2*x - 5
Those things are actually quite useful. Python supports a style of programming called functional programming where you can pass functions to other functions to do stuff. Example:
mult3 = filter(lambda x: x % 3 == 0, [1, 2, 3, 4, 5, 6, 7, 8, 9])
sets mult3 to [3, 6, 9], those elements of the original list that are multiples of 3. This is shorter (and, one could argue, clearer) than
def filterfunc(x):
return x % 3 == 0
mult3 = filter(filterfunc, [1, 2, 3, 4, 5, 6, 7, 8, 9])
Of course, in this particular case, you could do the same thing as a list comprehension:
mult3 = [x for x in [1, 2, 3, 4, 5, 6, 7, 8, 9] if x % 3 == 0]
(or even as range(3,10,3)), but there are many other, more sophisticated use cases where you can't use a list comprehension and a lambda function may be the shortest way to write something out.
Returning a function from another function
>>> def transform(n):
... return lambda x: x + n
...
>>> f = transform(3)
>>> f(4)
7
This is often used to create function wrappers, such as Python's decorators.
Combining elements of an iterable sequence with reduce()
>>> reduce(lambda a, b: '{}, {}'.format(a, b), [1, 2, 3, 4, 5, 6, 7, 8, 9])
'1, 2, 3, 4, 5, 6, 7, 8, 9'
Sorting by an alternate key
>>> sorted([1, 2, 3, 4, 5, 6, 7, 8, 9], key=lambda x: abs(5-x))
[5, 4, 6, 3, 7, 2, 8, 1, 9]
I use lambda functions on a regular basis. It took me a while to get used to them, but eventually I came to understand that they're a very valuable part of the language.
lambda is just a fancy way of saying function. Other than its name, there is nothing obscure, intimidating or cryptic about it. When you read the following line, replace lambda by function in your mind:
>>> f = lambda x: x + 1
>>> f(3)
4
It just defines a function of x. Some other languages, like R, say it explicitly:
> f = function(x) { x + 1 }
> f(3)
4
You see? It's one of the most natural things to do in programming.
The two-line summary:
Closures: Very useful. Learn them, use them, love them.
Python's lambda keyword: unnecessary, occasionally useful. If you find yourself doing anything remotely complex with it, put it away and define a real function.
A lambda is part of a very important abstraction mechanism which deals with higher order functions. To get proper understanding of its value, please watch high quality lessons from Abelson and Sussman, and read the book SICP
These are relevant issues in modern software business, and becoming ever more popular.
I doubt lambda will go away.
See Guido's post about finally giving up trying to remove it. Also see an outline of the conflict.
You might check out this post for more of a history about the deal behind Python's functional features:
http://python-history.blogspot.com/2009/04/origins-of-pythons-functional-features.html
Curiously, the map, filter, and reduce functions that originally motivated the introduction of lambda and other functional features have to a large extent been superseded by list comprehensions and generator expressions. In fact, the reduce function was removed from list of builtin functions in Python 3.0. (However, it's not necessary to send in complaints about the removal of lambda, map or filter: they are staying. :-)
My own two cents: Rarely is lambda worth it as far as clarity goes. Generally there is a more clear solution that doesn't include lambda.
lambdas are extremely useful in GUI programming. For example, lets say you're creating a group of buttons and you want to use a single paramaterized callback rather than a unique callback per button. Lambda lets you accomplish that with ease:
for value in ["one","two","three"]:
b = tk.Button(label=value, command=lambda arg=value: my_callback(arg))
b.pack()
(Note: although this question is specifically asking about lambda, you can also use functools.partial to get the same type of result)
The alternative is to create a separate callback for each button which can lead to duplicated code.
In Python, lambda is just a way of defining functions inline,
a = lambda x: x + 1
print a(1)
and..
def a(x): return x + 1
print a(1)
..are the exact same.
There is nothing you can do with lambda which you cannot do with a regular function—in Python functions are an object just like anything else, and lambdas simply define a function:
>>> a = lambda x: x + 1
>>> type(a)
<type 'function'>
I honestly think the lambda keyword is redundant in Python—I have never had the need to use them (or seen one used where a regular function, a list-comprehension or one of the many builtin functions could have been better used instead)
For a completely random example, from the article "Python’s lambda is broken!":
To see how lambda is broken, try generating a list of functions fs=[f0,...,f9] where fi(n)=i+n. First attempt:
>>> fs = [(lambda n: i + n) for i in range(10)]
>>> fs[3](4)
13
I would argue, even if that did work, it's horribly and "unpythonic", the same functionality could be written in countless other ways, for example:
>>> n = 4
>>> [i + n for i in range(10)]
[4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
Yes, it's not the same, but I have never seen a cause where generating a group of lambda functions in a list has been required. It might make sense in other languages, but Python is not Haskell (or Lisp, or ...)
Please note that we can use lambda and still achieve the desired
results in this way :
>>> fs = [(lambda n,i=i: i + n) for i in range(10)]
>>> fs[3](4)
7
Edit:
There are a few cases where lambda is useful, for example it's often convenient when connecting up signals in PyQt applications, like this:
w = PyQt4.QtGui.QLineEdit()
w.textChanged.connect(lambda event: dothing())
Just doing w.textChanged.connect(dothing) would call the dothing method with an extra event argument and cause an error. Using the lambda means we can tidily drop the argument without having to define a wrapping function.
I find lambda useful for a list of functions that do the same, but for different circumstances.
Like the Mozilla plural rules:
plural_rules = [
lambda n: 'all',
lambda n: 'singular' if n == 1 else 'plural',
lambda n: 'singular' if 0 <= n <= 1 else 'plural',
...
]
# Call plural rule #1 with argument 4 to find out which sentence form to use.
plural_rule[1](4) # returns 'plural'
If you'd have to define a function for all of those you'd go mad by the end of it.
Also, it wouldn't be nice with function names like plural_rule_1, plural_rule_2, etc. And you'd need to eval() it when you're depending on a variable function id.
Pretty much anything you can do with lambda you can do better with either named functions or list and generator expressions.
Consequently, for the most part you should just one of those in basically any situation (except maybe for scratch code written in the interactive interpreter).
I've been using Python for a few years and I've never run in to a case where I've needed lambda. Really, as the tutorial states, it's just for syntactic sugar.
Lambda function it's a non-bureaucratic way to create a function.
That's it. For example, let's supose you have your main function and need to square values. Let's see the traditional way and the lambda way to do this:
Traditional way:
def main():
...
...
y = square(some_number)
...
return something
def square(x):
return x**2
The lambda way:
def main():
...
square = lambda x: x**2
y = square(some_number)
return something
See the difference?
Lambda functions go very well with lists, like lists comprehensions or map. In fact, list comprehension it's a "pythonic" way to express yourself using lambda. Ex:
>>>a = [1,2,3,4]
>>>[x**2 for x in a]
[1,4,9,16]
Let's see what each elements of the syntax means:
[] : "Give me a list"
x**2 : "using this new-born function"
for x in a: "into each element in a"
That's convenient uh? Creating functions like this. Let's rewrite it using lambda:
>>> square = lambda x: x**2
>>> [square(s) for x in a]
[1,4,9,16]
Now let's use map, which is the same thing, but more language-neutral. Maps takes 2 arguments:
(i) one function
(ii) an iterable
And gives you a list where each element it's the function applied to each element of the iterable.
So, using map we would have:
>>> a = [1,2,3,4]
>>> squared_list = map(lambda x: x**2, a)
If you master lambdas and mapping, you will have a great power to manipulate data and in a concise way. Lambda functions are neither obscure nor take away code clarity. Don't confuse something hard with something new. Once you start using them, you will find it very clear.
I can't speak to python's particular implementation of lambda, but in general lambda functions are really handy. They're a core technique (maybe even THE technique) of functional programming, and they're also very useuful in object-oriented programs. For certain types of problems, they're the best solution, so certainly shouldn't be forgotten!
I suggest you read up on closures and the map function (that links to python docs, but it exists in nearly every language that supports functional constructs) to see why it's useful.
One of the nice things about lambda that's in my opinion understated is that it's way of deferring an evaluation for simple forms till the value is needed. Let me explain.
Many library routines are implemented so that they allow certain parameters to be callables (of whom lambda is one). The idea is that the actual value will be computed only at the time when it's going to be used (rather that when it's called). An (contrived) example might help to illustrate the point. Suppose you have a routine which which was going to do log a given timestamp. You want the routine to use the current time minus 30 minutes. You'd call it like so
log_timestamp(datetime.datetime.now() - datetime.timedelta(minutes = 30))
Now suppose the actual function is going to be called only when a certain event occurs and you want the timestamp to be computed only at that time. You can do this like so
log_timestamp(lambda : datetime.datetime.now() - datetime.timedelta(minutes = 30))
Assuming the log_timestamp can handle callables like this, it will evaluate this when it needs it and you'll get the timestamp at that time.
There are of course alternate ways to do this (using the operator module for example) but I hope I've conveyed the point.
Update: Here is a slightly more concrete real world example.
Update 2: I think this is an example of what is called a thunk.
As stated above, the lambda operator in Python defines an anonymous function, and in Python functions are closures. It is important not to confuse the concept of closures with the operator lambda, which is merely syntactic methadone for them.
When I started in Python a few years ago, I used lambdas a lot, thinking they were cool, along with list comprehensions. However, I wrote and have to maintain a big website written in Python, with on the order of several thousand function points. I've learnt from experience that lambdas might be OK to prototype things with, but offer nothing over inline functions (named closures) except for saving a few key-stokes, or sometimes not.
Basically this boils down to several points:
it is easier to read software that is explicitly written using meaningful names. Anonymous closures by definition cannot have a meaningful name, as they have no name. This brevity seems, for some reason, to also infect lambda parameters, hence we often see examples like lambda x: x+1
it is easier to reuse named closures, as they can be referred to by name more than once, when there is a name to refer to them by.
it is easier to debug code that is using named closures instead of lambdas, because the name will appear in tracebacks, and around the error.
That's enough reason to round them up and convert them to named closures. However, I hold two other grudges against anonymous closures.
The first grudge is simply that they are just another unnecessary keyword cluttering up the language.
The second grudge is deeper and on the paradigm level, i.e. I do not like that they promote a functional-programming style, because that style is less flexible than the message passing, object oriented or procedural styles, because the lambda calculus is not Turing-complete (luckily in Python, we can still break out of that restriction even inside a lambda). The reasons I feel lambdas promote this style are:
There is an implicit return, i.e. they seem like they 'should' be functions.
They are an alternative state-hiding mechanism to another, more explicit, more readable, more reusable and more general mechanism: methods.
I try hard to write lambda-free Python, and remove lambdas on sight. I think Python would be a slightly better language without lambdas, but that's just my opinion.
Lambdas are actually very powerful constructs that stem from ideas in functional programming, and it is something that by no means will be easily revised, redefined or removed in the near future of Python. They help you write code that is more powerful as it allows you to pass functions as parameters, thus the idea of functions as first-class citizens.
Lambdas do tend to get confusing, but once a solid understanding is obtained, you can write clean elegant code like this:
squared = map(lambda x: x*x, [1, 2, 3, 4, 5])
The above line of code returns a list of the squares of the numbers in the list. Ofcourse, you could also do it like:
def square(x):
return x*x
squared = map(square, [1, 2, 3, 4, 5])
It is obvious the former code is shorter, and this is especially true if you intend to use the map function (or any similar function that takes a function as a parameter) in only one place. This also makes the code more intuitive and elegant.
Also, as #David Zaslavsky mentioned in his answer, list comprehensions are not always the way to go especially if your list has to get values from some obscure mathematical way.
From a more practical standpoint, one of the biggest advantages of lambdas for me recently has been in GUI and event-driven programming. If you take a look at callbacks in Tkinter, all they take as arguments are the event that triggered them. E.g.
def define_bindings(widget):
widget.bind("<Button-1>", do-something-cool)
def do-something-cool(event):
#Your code to execute on the event trigger
Now what if you had some arguments to pass? Something as simple as passing 2 arguments to store the coordinates of a mouse-click. You can easily do it like this:
def main():
# define widgets and other imp stuff
x, y = None, None
widget.bind("<Button-1>", lambda event: do-something-cool(x, y))
def do-something-cool(event, x, y):
x = event.x
y = event.y
#Do other cool stuff
Now you can argue that this can be done using global variables, but do you really want to bang your head worrying about memory management and leakage especially if the global variable will just be used in one particular place? That would be just poor programming style.
In short, lambdas are awesome and should never be underestimated. Python lambdas are not the same as LISP lambdas though (which are more powerful), but you can really do a lot of magical stuff with them.
Lambdas are deeply linked to functional programming style in general. The idea that you can solve problems by applying a function to some data, and merging the results, is what google uses to implement most of its algorithms.
Programs written in functional programming style, are easily parallelized and hence are becoming more and more important with modern multi-core machines.
So in short, NO you should not forget them.
First congrats that managed to figure out lambda. In my opinion this is really powerful construct to act with. The trend these days towards functional programming languages is surely an indicator that it neither should be avoided nor it will be redefined in the near future.
You just have to think a little bit different. I'm sure soon you will love it. But be careful if you deal only with python. Because the lambda is not a real closure, it is "broken" somehow: pythons lambda is broken
I'm just beginning Python and ran head first into Lambda- which took me a while to figure out.
Note that this isn't a condemnation of anything. Everybody has a different set of things that don't come easily.
Is lambda one of those 'interesting' language items that in real life should be forgotten?
No.
I'm sure there are some edge cases where it might be needed, but given the obscurity of it,
It's not obscure. The past 2 teams I've worked on, everybody used this feature all the time.
the potential of it being redefined in future releases (my assumption based on the various definitions of it)
I've seen no serious proposals to redefine it in Python, beyond fixing the closure semantics a few years ago.
and the reduced coding clarity - should it be avoided?
It's not less clear, if you're using it right. On the contrary, having more language constructs available increases clarity.
This reminds me of overflowing (buffer overflow) of C types - pointing to the top variable and overloading to set the other field values...sort of a techie showmanship but maintenance coder nightmare..
Lambda is like buffer overflow? Wow. I can't imagine how you're using lambda if you think it's a "maintenance nightmare".
A useful case for using lambdas is to improve the readability of long list comprehensions.
In this example loop_dic is short for clarity but imagine loop_dic being very long. If you would just use a plain value that includes i instead of the lambda version of that value you would get a NameError.
>>> lis = [{"name": "Peter"}, {"name": "Josef"}]
>>> loop_dic = lambda i: {"name": i["name"] + " Wallace" }
>>> new_lis = [loop_dic(i) for i in lis]
>>> new_lis
[{'name': 'Peter Wallace'}, {'name': 'Josef Wallace'}]
Instead of
>>> lis = [{"name": "Peter"}, {"name": "Josef"}]
>>> new_lis = [{"name": i["name"] + " Wallace"} for i in lis]
>>> new_lis
[{'name': 'Peter Wallace'}, {'name': 'Josef Wallace'}]
I use lambdas to avoid code duplication. It would make the function easily comprehensible
Eg:
def a_func()
...
if some_conditon:
...
call_some_big_func(arg1, arg2, arg3, arg4...)
else
...
call_some_big_func(arg1, arg2, arg3, arg4...)
I replace that with a temp lambda
def a_func()
...
call_big_f = lambda args_that_change: call_some_big_func(arg1, arg2, arg3, args_that_change)
if some_conditon:
...
call_big_f(argX)
else
...
call_big_f(argY)
I started reading David Mertz's book today 'Text Processing in Python.' While he has a fairly terse description of Lambda's the examples in the first chapter combined with the explanation in Appendix A made them jump off the page for me (finally) and all of a sudden I understood their value. That is not to say his explanation will work for you and I am still at the discovery stage so I will not attempt to add to these responses other than the following:
I am new to Python
I am new to OOP
Lambdas were a struggle for me
Now that I read Mertz, I think I get them and I see them as very useful as I think they allow a cleaner approach to programming.
He reproduces the Zen of Python, one line of which is Simple is better than complex. As a non-OOP programmer reading code with lambdas (and until last week list comprehensions) I have thought-This is simple?. I finally realized today that actually these features make the code much more readable, and understandable than the alternative-which is invariably a loop of some sort. I also realized that like financial statements-Python was not designed for the novice user, rather it is designed for the user that wants to get educated. I can't believe how powerful this language is. When it dawned on me (finally) the purpose and value of lambdas I wanted to rip up about 30 programs and start over putting in lambdas where appropriate.
I can give you an example where I actually needed lambda serious. I'm making a graphical program, where the use right clicks on a file and assigns it one of three options. It turns out that in Tkinter (the GUI interfacing program I'm writing this in), when someone presses a button, it can't be assigned to a command that takes in arguments. So if I chose one of the options and wanted the result of my choice to be:
print 'hi there'
Then no big deal. But what if I need my choice to have a particular detail. For example, if I choose choice A, it calls a function that takes in some argument that is dependent on the choice A, B or C, TKinter could not support this. Lamda was the only option to get around this actually...
I use it quite often, mainly as a null object or to partially bind parameters to a function.
Here are examples:
to implement null object pattern:
{
DATA_PACKET: self.handle_data_packets
NET_PACKET: self.handle_hardware_packets
}.get(packet_type, lambda x : None)(payload)
for parameter binding:
let say that I have the following API
def dump_hex(file, var)
# some code
pass
class X(object):
#...
def packet_received(data):
# some kind of preprocessing
self.callback(data)
#...
Then, when I wan't to quickly dump the recieved data to a file I do that:
dump_file = file('hex_dump.txt','w')
X.callback = lambda (x): dump_hex(dump_file, x)
...
dump_file.close()
I use lambda to create callbacks that include parameters. It's cleaner writing a lambda in one line than to write a method to perform the same functionality.
For example:
import imported.module
def func():
return lambda: imported.module.method("foo", "bar")
as opposed to:
import imported.module
def func():
def cb():
return imported.module.method("foo", "bar")
return cb
I'm a python beginner, so to getter a clear idea of lambda I compared it with a 'for' loop; in terms of efficiency.
Here's the code (python 2.7) -
import time
start = time.time() # Measure the time taken for execution
def first():
squares = map(lambda x: x**2, range(10))
# ^ Lambda
end = time.time()
elapsed = end - start
print elapsed + ' seconds'
return elapsed # gives 0.0 seconds
def second():
lst = []
for i in range(10):
lst.append(i**2)
# ^ a 'for' loop
end = time.time()
elapsed = end - start
print elapsed + ' seconds'
return elapsed # gives 0.0019998550415 seconds.
print abs(second() - first()) # Gives 0.0019998550415 seconds!(duh)
Lambda is a procedure constructor. You can synthesize programs at run-time, although Python's lambda is not very powerful. Note that few people understand that kind of programming.
Related
I've been a procedural programmer for a while now, and just trying to switch my mindset to use functional programming (in Python 3 for now).
So, instead of writing a for-each loop, I'm trying to grasp the interaction between map and list(map(..))
Lets say I have a simple for-in loop which does some resource heavy computation (which I'll replace with print here for the sake of simplicity):
arr = [1,2,3,4]
for x in arr:
print(x)
Now, when I try to do the following
map(lambda x: print(x), arr)
nothing happens, UNTIL, i wrap this in a list and it does my super heavy print function:
list(map(lambda x: print(x), arr))
Why? What am I missing? I understand map returns an iterator which is supposed to save memory instead of just holding the entire list right away. But when is my super heavy print function going to be triggered then?
Why? What am I missing? I understand map returns an iterator which is supposed to save memory instead of just holding the entire list right away. But when is my super heavy print function going to be triggered then?
The map function is what's commonly known in programmer terminology as lazy. It won't do any work unless it has to. This is more broadly known as in functional programming as lazy evaluation. Rather than immediately compute any values, the map function instead returns what's known as an iterator. By doing this, it's delegating the job of compute the values it was given back to you.
A single value can be computed by the iterator using next:
>>> arr = [1, 2, 3]
>>> it = map(lambda x: print(x), arr)
>>> next(it)
1
>>>
However, when you casted the map iterator to be a list, you were forcing map to compute all of its values and thus call your function:
>>> it = map(lambda x: print(x), arr)
>>> list(it)
1
2
3
4
[None, None, None, None]
>>>
As you said, you have to switch your mindset to use functional programming. One of the key concepts of functional programming is lazy evaluation, which is the default policy in languages such as Haskell.
The purpose of this policy is to save both time and memory, by calculating something only when it is needed. In that sense Python generators are also close to the functional paradigm.
If you want to execute it as soon as possible, you shouldn't write it in a functional style and fix it with list() if you don't care about the results. Using a loop is totally ok.
I can find lots of stuff showing me what a lambda function is, and how the syntax works and what not. But other than the "coolness factor" (I can make a function in middle a call to another function, neat!) I haven't seen something that's overwelmingly compelling to say why I really need/want to use them.
It seems to be more of a stylistic or structual choice in most examples I've seen. And kinda breaks the "Only one correct way to do something" in python rule. How does it make my programs, more correct, more reliable, faster, or easier to understand? (Most coding standards I've seen tend to tell you to avoid overly complex statements on a single line. If it makes it easier to read break it up.)
Here's a good example:
def key(x):
return x[1]
a = [(1, 2), (3, 1), (5, 10), (11, -3)]
a.sort(key=key)
versus
a = [(1, 2), (3, 1), (5, 10), (11, -3)]
a.sort(key=lambda x: x[1])
From another angle: Lambda expressions are also known as "anonymous functions", and are very useful in certain programming paradigms, particularly functional programming, which lambda calculus provided the inspiration for.
http://en.wikipedia.org/wiki/Lambda_calculus
The syntax is more concise in certain situations, mostly when dealing with map et al.
map(lambda x: x * 2, [1,2,3,4])
seems better to me than:
def double(x):
return x * 2
map(double, [1,2,3,4])
I think the lambda is a better choice in this situation because the def double seems almost disconnected from the map that is using it. Plus, I guess it has the added benefit that the function gets thrown away when you are done.
There is one downside to lambda which limits its usefulness in Python, in my opinion: lambdas can have only one expression (i.e., you can't have multiple lines). It just can't work in a language that forces whitespace.
Plus, whenever I use lambda I feel awesome.
For me it's a matter of the expressiveness of the code. When writing code that people will have to support, that code should tell a story in as concise and easy to understand manner as possible. Sometimes the lambda expression is more complicated, other times it more directly tells what that line or block of code is doing. Use judgment when writing.
Think of it like structuring a sentence. What are the important parts (nouns and verbs vs. objects and methods, etc.) and how should they be ordered for that line or block of code to convey what it's doing intuitively.
Lambda functions are most useful in things like callback functions, or places in which you need a throwaway function. JAB's example is perfect - It would be better accompanied by the keyword argument key, but it still provides useful information.
When
def key(x):
return x[1]
appears 300 lines away from
[(1,2), (3,1), (5,10), (11,-3)].sort(key)
what does key do? There's really no indication. You might have some sort of guess, especially if you're familiar with the function, but usually it requires going back to look. OTOH,
[(1,2), (3,1), (5,10), (11,-3)].sort(lambda x: x[1])
tells you a lot more.
Sort takes a function as an argument
That function takes 1 parameter (and "returns" a result)
I'm trying to sort this list by the 2nd value of each of the elements of the list
(If the list were a variable so you couldn't see the values) this logic expects the list to have at least 2 elements in it.
There's probably some more information, but already that's a tremendous amount that you get just by using an anonymous lambda function instead of a named function.
Plus it doesn't pollute your namespace ;)
Yes, you're right — it is a structural choice. It probably does not make your programs more correct by just using lambda expressions. Nor does it make them more reliable, and this has nothing to do with speed.
It is only about flexibility and the power of expression. Like list comprehension. You can do most of that defining named functions (possibly polluting namespace, but that's again purely stylistic issue).
It can aid to readability by the fact, that you do not have to define a separate named function, that someone else will have to find, read and understand that all it does is to call a method blah() on its argument.
It may be much more interesting when you use it to write functions that create and return other functions, where what exactly those functions do, depends on their arguments. This may be a very concise and readable way of parameterizing your code behaviour. You can just express more interesting ideas.
But that is still a structural choice. You can do that otherwise. But the same goes for object oriented programming ;)
Ignore for a moment the detail that it's specifically anonymous functions we're talking about. functions, including anonymous ones, are assignable quantities (almost, but not really, values) in Python. an expression like
map(lambda y: y * -1, range(0, 10))
explicitly mentions four anonymous quantities: -1, 0, 10 and the result of the lambda operator, plus the implied result of the map call. it's possible to create values of anonymous types in some languages. so ignore the superficial difference between functions and numbers. the question when to use an anonymous function as opposed to a named one is similar to a question of when to put a naked number literal in the code and when to declare a TIMES_I_WISHED_I_HAD_A_PONY or BUFFER_SIZE beforehand. there are times when it's appropriate to use a (numeric, string or function) literal, and there are times when it's more appropriate to name such a thing and refer to it through its name.
see eg. Allen Holub's provocative, thought-or-anger-provoking book on Design Patterns in Java; he uses anonymous classes quite a bit.
Lambda, while useful in certain situations, has a large potential for abuse. lambda's almost always make code more difficult to read. And while it might feel satisfying to fit all your code onto a single line, it will suck for the next person who has to read your code.
Direct from PEP8
"One of Guido's key insights is that code is read much more often than it is written."
It is definitely true that abusing lambda functions often leads to bad and hard-to-read code. On the other hand, when used accurately, it does the opposite. There are already great answers in this thread, but one example I have come across is:
def power(n):
return lambda x: x**n
square = power(2)
cubic = power(3)
quadruple = power(4)
print(square(10)) # 100
print(cubic(10)) # 1000
print(quadruple(10)) # 10000
This simplified case could be rewritten in many other ways without the use of lambda. Still, one can infer how lambda functions can increase readability and code reuse in perhaps more complex cases and functions with this example.
Lambdas are anonymous functions (function with no name) that can be assigned to a variable or that can be passed as an argument to another function. The usefulness of lambda will be realized when you need a small piece of function that will be run once in a while or just once. Instead of writing the function in global scope or including it as part of your main program you can toss around few lines of code when needed to a variable or another function. Also when you pass the function as an argument to another function during the function call you can change the argument (the anonymous function) making the function itself dynamic. Suppose if the anonymous function uses variables outside its scope it is called closure. This is useful in callback functions.
One use of lambda function which I have learned, and where is not other good alternative or at least looks for me best is as default action in function parameter by
parameter=lambda x: x
This returns the value without change, but you can supply one function optionally to perform a transformation or action (like printing the answer, not only returning)
Also often it is useful to use in sorting as key:
key=lambda x: x[field]
The effect is to sort by fieldth (zero based remember) element of each item in sequence. For reversing you do not need lambda as it is clearer to use
reverse=True
Often it is almost as easy to do new real function and use that instead of lambda. If people has studied much Lisp or other functional programming, they also have natural tendency to use lambda function as in Lisp the function definitions are handled by lambda calculus.
Lambdas are objects, not methods, and they cannot be invoked in the same way that methods are.
for e.g
succ = ->(x){ x+1 }
succ mow holds a Proc object, which we can use like any other:
succ.call(2)
gives us an output = 3
I want to point out one situation other than list-processing where the lambda functions seems the best choice:
from tkinter import *
from tkinter import ttk
def callback(arg):
print(arg)
pass
root = Tk()
ttk.Button(root, text = 'Button1', command = lambda: callback('Button 1 clicked')).pack()
root.mainloop()
And if we drop lambda function here, the callback may only execute the callback once.
ttk.Button(root, text = 'Button1', command = callback('Button1 clicked')).pack()
Another point is that python does not have switch statements. Combining lambdas with dicts can be an effective alternative. e.g.:
switch = {
'1': lambda x: x+1,
'2': lambda x: x+2,
'3': lambda x: x+3
}
x = starting_val
ans = expression
new_ans = switch[ans](x)
In some cases it is much more clear to express something simple as a lambda. Consider regular sorting vs. reverse sorting for example:
some_list = [2, 1, 3]
print sorted(some_list)
print sorted(some_list, lambda a, b: -cmp(a, b))
For the latter case writing a separate full-fledged function just to return a -cmp(a, b) would create more misunderstanding then a lambda.
Lambdas allow you to create functions on the fly. Most of the examples I've seen don't do much more than create a function with parameters passed at the time of creation rather than execution. Or they simplify the code by not requiring a formal declaration of the function ahead of use.
A more interesting use would be to dynamically construct a python function to evaluate a mathematical expression that isn't known until run time (user input). Once created, that function can be called repeatedly with different arguments to evaluate the expression (say you wanted to plot it). That may even be a poor example given eval(). This type of use is where the "real" power is - in dynamically creating more complex code, rather than the simple examples you often see which are not much more than nice (source) code size reductions.
you master lambda, you master shortcuts in python.Here is why:
data=[(lambda x:x.text)(x.extract()) for x in soup.findAll('p') ]
^1 ^2 ^3 ^4
here we can see 4 parts of the list comprehension:
1: i finally want this
2: x.extract will perform some operation on x, here it pop the element from soup
3: x is the list iterable which is passed to the input of lambda at 2 along with extract operation
4: some arbitary list
i had found no other way to use 2 statements in lambda, but with this
kind of pipe-lining we can exploit the infinite potential of lambda.
Edit: as pointed out in the comments, by juanpa, its completely fine to use x.extract().text but the point was explaining the use of lambda pipe, ie passing the output of lambda1 as input to lambda2. via (lambda1 y:g(x))(lambda2 x:f(x))
Why was Python's filter designed such that if you run filter(my_predicate, some_set), I get back a list object return than a set object?
Are there practical cases where you would not want the result to be a set...?
You can do a set comprehension.
{my_predicate(x) for x in some_set} # mapping
{x for x in some_set if my_predicate(x)} # filtering
such as
In [1]: s = set([1,2,3])
In [2]: {x%2 for x in s}
Out[2]: {0, 1}
Many of the "functional" functions in Python 2 are standardized on having list as the output type. This was just an API choice long ago. In itertools many of the same "functional" functions standardize on providing a generator from which you could populate whatever data structure you'd like. And in Python 3 they are standardized on providing an iterator.
But do also note that "filtering" in Python is not like it is in some other languages, like, say Haskell. It's not considered to be a transformation within the context of the data structure, and you don't choose to "endow" your data structures with "filterability" by making them an instance of Functor (or whatever other similar ideas exist in other languages).
As a result, it's a common use case in Python to say something like: "Here's a set, but I just want back all of the values less than 5. I don't care about their 'set-ness' after that point cause I'm just going to do some other work on them, so just give me a ____." No need to get all crazy about preserving the context within which the values originally lived.
In a dynamic typing culture this is very reasonable. But in a static typing culture where preserving the type during transformations might matter, this would be a bit frustrating. It's really just sort of a heuristic from Python's particular perspective.
If it was really just in a very narrow context of a set or tuple then I might just write a helper function:
def type_preserving_filter(predicate, data):
return type(data)(filter(predicate, data))
such as
>>> type_preserving_filter(lambda x: x > 3, set([1,2,3,4,5,6,7,7]))
{4, 5, 6, 7}
>>> type_preserving_filter(lambda x: x > 3, list([1,2,3,4,5,6,7,7]))
[4, 5, 6, 7, 7]
>>> type_preserving_filter(lambda x: x > 3, tuple([1,2,3,4,5,6,7,7]))
(4, 5, 6, 7, 7)
which works in both Python 2.10 and Python 3.4. In Python 2 this feels a bit wasteful; constructing from the iterator in Python 3 is better.
This is not limited to filter(). But the API has changed in Python 3, where filter() now returns an iterator instead of a list. Quoting the python documentation:
Views And Iterators Instead Of Lists
Some well-known APIs no longer return lists:
...
map() and
filter()
return iterators. If you really need a list, a quick fix is e.g.
list(map(...)), but a better fix is often to use a list
comprehension (especially when the original code uses lambda), or
rewriting the code so it doesn’t need a list at all. Particularly
tricky is map() invoked for the side effects of the function; the
correct transformation is to use a regular for loop (since creating a
list would just be wasteful).
This article written by the author of Python goes into detail for reasons for dropping filter() in Python 3 (but this did not happen as you can see above, although the reasoning is still important.)
The fate of reduce() in Python 3000
...
I think dropping filter() and map() is pretty uncontroversial;
filter(P, S) is almost always written clearer as [x for x in S if P(x)], and this has the huge advantage that the most common usages
involve predicates that are comparisons, e.g. x==42, and defining a
lambda for that just requires much more effort for the reader (plus
the lambda is slower than the list comprehension). Even more so for
map(F, S) which becomes [F(x) for x in S]. Of course, in many
cases you'd be able to use generator expressions instead.
What is considered to be a better programming practice when dealing with more object at time (but with the option to process just one object)?
A: LOOP INSIDE FUNCTION
Function can be called with one or more objects and it is iterating inside function:
class Object:
def __init__(self, a, b):
self.var_a = a
self.var_b = b
var_a = ""
var_b = ""
def func(obj_list):
if type(obj_list) != list:
obj_list = [obj_list]
for obj in obj_list:
# do whatever with an object
print(obj.var_a, obj.var_b)
obj_list = [Object("a1", "a2"), Object("b1", "b2")]
obj_alone = Object("c1", "c2")
func(obj_list)
func(obj_alone)
B: LOOP OUTSIDE FUNCTION
Function is dealing with one object only and when it is dealing with more objects in must be called multiple times.
class Object:
def __init__(self, a, b):
self.var_a = a
self.var_b = b
var_a = ""
var_b = ""
def func(obj):
# do whatever with an object
print(obj.var_a, obj.var_b)
obj_list = [Object("a1", "a2"), Object("b1", "b2")]
obj_alone = Object("c1", "c2")
for obj in obj_list:
func(obj)
func(obj_alone)
I personally like the first one (A) more, because for me it makes cleaner code when calling the function, but maybe it's not the right approach. Is there some method generally better than the other? And if not, what are the cons and pros of each method?
A function should have a defined input and output and follow the single responsibility principle. You need to be able to clearly define your function in terms of "I put foo in, I get bar back". The more qualifiers you need to make in this statement to properly describe your function probably means your function is doing too much. "I put foo in and get bar back, unless I put baz in then I also get bar back, unless I put a foo-baz in then it'll error".
In this particular case, you can pass an object or a list of objects. Try to generalise that to a value or a list of values. What if you want to pass a list as a value? Now your function behaviour is ambiguous. You want the single list object to be your value, but the function treats it as multiple arguments instead.
Therefore, it's trivial to adapt a function which takes one argument to work on multiple values in practice. There's no reason to complicate the function's design by making it adaptable to multiple arguments. Write the function as simple and clearly as possible, and if you need it to work through a list of things then you can loop it through that list of things outside the function.
This might become clearer if you try to give an actual useful name to your function which describes what it does. Do you need to use plural or singular terms? foo_the_bar(bar) does something else than foo_the_bars(bars).
Move loops outside functions (when possible)
Generally speaking, keep loops that do nothing but iterate over the parameter outside of functions. This gives the caller maximum control and assumes the least about how the client will use the function.
The rule of thumb is to use the most minimal parameter complexity that the function needs do its job.
For example, let's say you have a function that processes one item. You've anticipated that a client might conceivably want to process multiple items, so you changed the parameter to an iterable, baked a loop into the function, and are now returning a list. Why not? It could save the client from writing an ugly loop in the caller, you figure, and the basic functionality is still available -- and then some!
But this turns out to be a serious constraint. Now the caller needs to pack (and possibly unpack, if the function returns a list of results in addition to a list of arguments) that single item into a list just to use the function. This is confusing and potentially expensive on heap memory:
>>> def square(it): return [x ** 2 for x in it]
...
>>> square(range(6)) # you're thinking ...
[0, 1, 4, 9, 16, 25]
>>> result, = square([3]) # ... but the client just wants to square 1 number
>>> result
9
Here's a much better design for this particular function, intuitive and flexible:
>>> def square(x): return x ** 2
...
>>> square(3)
9
>>> [square(x) for x in range(6)]
[0, 1, 4, 9, 16, 25]
>>> list(map(square, range(6)))
[0, 1, 4, 9, 16, 25]
>>> (square(x) for x in range(6))
<generator object <genexpr> at 0x00000166D122CBA0>
>>> all(square(x) % 2 for x in range(6))
False
This brings me to a second problem with the functions in your code: they have a side-effect, print. I realize these functions are just for demonstration, but designing functions like this makes the example somewhat contrived. Functions typically return values rather than simply produce side-effects, and the parameters and return values are often related, as in the above example -- changing the parameter type bound us to a different return type.
When does it make sense to use an iterable argument? A good example is sort -- the smallest unit of operation for a sorting function is an iterable, so the problem of packing and unpacking in the square example above is a non-issue.
Following this logic a step further, would it make sense for a sort function to accept a list (or variable arguments) of lists? No -- if the caller wants to sort multiple lists, they should loop over them explicitly and call sort on each one, as in the second square example.
Consider variable arguments
A nice feature that bridges the gap between iterables and single arguments is support for variable arguments, which many languages offer. This sometimes gives you the best of both worlds, and some functions go so far as to accept either args or an iterable:
>>> max([1, 3, 2])
3
>>> max(1, 3, 2)
3
One reason max is nice as a variable argument function is that it's a reduction function, so you'll always get a single value as output. If it were a mapping or filtering function, the output is always a list (or generator) so the input should be as well.
To take another example, a sort routine wouldn't make much sense with varargs because it's a classically in-place algorithm that works on lists, so you'd need to unpack the list into the arguments with the * operator pretty much every time you invoke the function -- not cool.
There's no real need for a call like sort(1, 3, 4, 2) as there is with max, where the parameters are just as likely to be loose variables as they are a packed iterable. Varargs are usually used when you have a small number of arguments, or the thing you're unpacking is a small pair or tuple-type element, as often the case with zip.
There's definitely a "feel" to when to offer parameters as varargs, an iterable, or a single value (i.e. let the caller handle looping), but as long as you follow the rule of avoiding iterables unless they're essential to the function, it's hard to go wrong.
As a final tip, try to write your functions with similar contracts to the library functions in your language or the tools you use frequently. These are pretty much always designed well; mimic good design.
If you implement B then you will make it harder for yourself to achieve A.
If you implement A then it isn't too difficult to achieve B. You also have many tools already available to apply this function to a list of arguments (the loop method you described, using something like map, or even a multiprocessing approach if needed)
Therefore I would choose to implement A, and if it makes things neater or easier in a given case you can think about also implementing B (using A) also so that you have both.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 months ago.
Improve this question
Functional programming is one of the programming paradigms in Python. It treats computation as the evaluation of mathematical functions and avoids state and mutable data. I am trying to understand how Python incorporates functional programming.
Consider the following factorial program (factorial.py):
def factorial(n, total):
if n == 0:
return total
else:
return factorial(n-1, total*n)
num = raw_input("Enter a natural number: ")
print factorial(int(num), 1)
That code avoids mutable data, because we are not changing the value of any variable. We are only recursively calling the factorial function with a new value.
If the example given above for functional programming is correct, then what does avoiding state mean?
Does functional programming only mean that I must use only functions whenever I have computations (as given in the above example)?
If the given example is wrong, what is a simple example with an explanation?
The example is correct for functional programming. And a good example of what not to do in Python because it is inefficient and doesn't scale. Python doesn't have any tail-call optimisation, so recursive calls should not be used solely to avoid imperative loops. If you really start programming in this style in Python, your programs will end with runtime errors eventually.
You are describing pure functional programming which is not something Python could be used for.
Python supports functional programming to some degree in the sense that functions are first class values. That means functions can be passed to other functions and returned as results from functions. And the standard library contains functions also found in most functional programming languages standard libraries, like map(), filter(), reduce(), and the stuff in the functools and itertools modules.
Borrowing from http://ua.pycon.org/static/talks/kachayev/#/8 where he makes a comparison between the way one thinks of imperative and functional programs. The example is borrowed.
Imperative:
expr, res = "28+32+++32++39", 0
for t in expr.split("+"):
if t != "":
res += int(t)
print res
Functional:
from operator import add
expr = "28+32+++32++39"
print reduce(add, map(int, filter(bool, expr.split("+"))))
If the given example is wrong, then kindly provide another simple example with an explanation.
It’s not, and it shows a realistic problem to start with, which you’ll see if you call factorial with a huge number. The maximum recursion depth will be reached. Python doesn’t have tail call optimization.
It the example given above for functional programming is correct, then what does avoiding state mean.
It means (in Python) that once a variable had been assigned, you should not reassign a new value, or change the value that you assigned to that variable.
Secondly, does functional programming only mean that, I must use only functions whenever I have computations (as given in the above example)
Functional programming is quite broad. Python is a multi-paradigm language that supports some functional programming concepts.
Functional programming means that all computations should be seen as mathematical functions.
I wrote a post about it that explains all the above in greater detail: Use Functional Programming In Python
Basics
Functional programming is a paradigm where we use only expressions and no statements. Statements do something like an if, whereas expressions evaluate mathematical stuff. We try to avoid mutability (values getting changed), since we only want pure functions. Pure functions don't have side effects, meaning that a function, given the same input, always produces the same output. We want functions to be pure, since they are easier to debug. By doing this, we are describing what a function is, as opposed to giving steps about how to do something and we write a lot less code. Functional programming is often called declarative, while other approaches are called imperative.
Utilities
Know about built-in functions, since they are so useful. For starters: abs, round, pow, max & min, sum, len, sorted, reversed, zip, and range.
Lambdas
Anonymous functions or lambdas are pure functions that take input and produce a value. There isn't any return statement, since we are returning what we are evaluating. You can also give them a name by just declaring a variable.
(lambda x, y: x + y)(1, 1)
add = lambda x, y: x + y
add(1, 1)
Ternary operator
Since we are working with expressions, instead of using if statements for logic, we use the ternary operator.
(expression) if (condition) else (expression2)
Map, filter & reduce
We also need a way of looping. This comes with list comprehension.
In this example we add one to each array element.
inc = lambda x: [i + 1 for i in x]
We can also operate on elements that meet a condition.
evens = lambda x: [i for i in x if (i % 2) == 0]
Some people say that that is the correct Pythonic way of doing things. But people who are more serious use a different approach: map, filter, and reduce. These are the building blocks of functional programming. While map and filter are built-in functions, reduce used to be, but now is in the functools module. To use it, import it:
from functools import reduce
Map is a function that takes a function and calls it on the elements of an array. The result of a map function is unfortunately unreadable, so you need to turn it into a tuple or a collection.
inc = lambda x: tuple(map(lambda y: y + 1, x))
Filter is a function that calls a function on an array, keeps the elements that output True and removes the ones that are False. Like map, it's not readable.
evens = lambda x: tuple(filter(lambda y: (y % 2) == 0, x))
Reduce takes a function that has two parameters. One is the result of the last time it was called & one is the new value. It keeps doing this until it reduces down to a value.
from functools import reduce
m_sum = lambda x: reduce(lambda y, z: y + z, x)
Let and do
A lot of functional programming languages have do. Do is a function that takes n arguments, evaluates all of them and returns the value of the last one. Python doesn't have do, but I created one myself.
do = lambda *args: tuple(map(lambda y: y, args))[-1]
Here's an example using do that prints something and exits.
print_err = lambda x: do(print(x), exit())
We use do to get imperative advantages.
Let allows some expression to be equal to something in a expression. In Python, most people do that as follows.
def something(x):
y = x + 10
return y * 3
Python 3.8 adds the expression assignment operators :=. So that code can now be written as a lambda.
something = lambda x: do(y := x + 10, y * 3)
Working with impure systems
The console, the file system, the web, etc. are immutable and impure and we need a way to work with them. In some languages like Haskell you have monads, which are wrappers for functions. Clojure allows the use of impure functions. In Python, a multi-paradigm language, we don't need anything, since it's not just functional. Print is an impure function.
Recursion
Your example uses recursion. Recursion uses the call stack, which is a small chunk of memory that is used for calling functions. It can get full and crash. A lot of functional programming languages use something known as lazy evaluation to help with the problem of recursion, but Python doesn't have it. So avoid recursion as much as possible.
Answers
Avoiding state is being immutable, meaning not changing the value of something.
In functional programming, everything is an expression, which is a function. We don't have that in Python though, since it's multi-paradigm.
In a more functional way, your code would be written as follows. Also it's not functional due to using an if statement instead of a ternary expression.
from functools import reduce
factorial = lambda x: reduce(lambda y, z: y*z, range(1,x+1))
This produces a range of 1 to x and multiplies all the values using range.