- Stack Overflow Public questions & answers
- Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
- Talent Build your employer brand
- Advertising Reach developers & technologists worldwide
- About the company

Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
E731 do not assign a lambda expression, use a def
I get this pep8 warning whenever I use lambda expressions. Are lambda expressions not recommended? If not why?
- 8 For clarity, the question refers to a message for an automated check in flake8 ( flake8.pycqa.org ) – rakslice Oct 31, 2018 at 1:10
5 Answers 5
The recommendation in PEP-8 you are running into is:
Always use a def statement instead of an assignment statement that binds a lambda expression directly to a name. Yes: def f(x): return 2*x No: f = lambda x: 2*x The first form means that the name of the resulting function object is specifically 'f' instead of the generic '<lambda>'. This is more useful for tracebacks and string representations in general. The use of the assignment statement eliminates the sole benefit a lambda expression can offer over an explicit def statement (i.e. that it can be embedded inside a larger expression)
Assigning lambdas to names basically just duplicates the functionality of def - and in general, it's best to do something a single way to avoid confusion and increase clarity.
The legitimate use case for lambda is where you want to use a function without assigning it, e.g:
In general, the main argument against doing this is that def statements will result in more lines of code. My main response to that would be: yes, and that is fine. Unless you are code golfing, minimising the number of lines isn't something you should be doing: go for clear over short.
- 17 I don't see how it's worse. The traceback is still going to include the errant line number and source file. One might say "f" whereas the other says "lambda". Maybe the lambda error is easier to scan because it's not a single-character function name, or a poorly-named long name? – user67416 Feb 17, 2015 at 19:08
- 6 @g33kz0r Well, sure, if you assume the rest of your code is going to have poor quality, following conventions won't gain you much. In general, no, it's not the end of the world, but it's still a bad idea. – Gareth Latty Feb 17, 2015 at 20:42
- 67 This answer is not very helpful, because when running the suggested approach of using def through the PEP8 checker, you get E704 multiple statements on one line (def) , and if you split it into two lines you get E301 expected 1 blank line, found 0 :-/ – Adam Spiers Feb 20, 2015 at 14:10
- 5 I agree it should be split. My points were that a) it is not split in the answer's code above, causing E704, and b) if you split it, you need an ugly blank line above it to avoid E301. – Adam Spiers Feb 21, 2015 at 2:10
- 5 I use lambdas when I want to emphasize a pure function (no side effects), and sometimes I have to use the same function in two places, i.e. groupby and sort together. So I ignore this convention. – manu Jan 28, 2016 at 21:53
Here is the story, I had a simple lambda function which I was using twice.
This is just for the representation, I have faced couple of different versions of this.
Now, to keep things DRY, I start to reuse this common lambda.
At this point my code quality checker complains about lambda being a named function so I convert it into a function.
Now the checker complains that a function has to be bounded by one blank line before and after.
Here we have now 6 lines of code instead of original 2 lines with no increase in readability and no increase in being pythonic. At this point the code checker complains about the function not having docstrings.
In my opinion this rule better be avoided and broken when it makes sense, use your judgement.

- 21 a = [x + offset for x in simple_list] . No need to use map and lambda here. – Georgy Apr 23, 2018 at 16:39
- 21 @Georgy I believe the point was to move the x + offset portion to an abstracted location that can be updated without changing more than one line of code. With list comprehensions as you mentioned, you would still need two lines of code that contained x + offset they would just now be in list comprehensions. In order to pull those out as the author wanted, you would need a def or lambda . – Julian Nov 3, 2018 at 2:18
- 1 @Julian Apart from def and lambda one could also use functools.partial : f = partial(operator.add, offset) and then a = list(map(f, simple_list)) . – Georgy Nov 18, 2018 at 18:33
- 1 What about def f(x): return x + offset (i.e., a simple function defined on a single line)? At least with flake8 I do not get complaints about blank lines. – DocOc Aug 22, 2019 at 10:50
- 1 @Julian In some cases you can use a nested comprehension: a, b = [[x + offset for x lst] for lst in (simple_list, another_simple_list)] – wjandrea Dec 29, 2019 at 21:03
Lattyware is absolutely right: Basically PEP-8 wants you to avoid things like
and instead use
However, as addressed in a recent bugreport (Aug 2014), statements such as the following are now compliant:
Since my PEP-8 checker doesn't implement this correctly yet, I turned off E731 for the time being.

- 12 Even when using def , the PEP8 checker complains with E301 expected 1 blank line, found 0 , so you then have to add an ugly blank line before it. – Adam Spiers Feb 20, 2015 at 14:11
- I don't think it's just against having assignments in lambda. I have no assignments in mine, just True or False return, yet it gives me C3001 (unnecessary-lambda-assignment) has_attribute = lambda x: x["attribute_name"] != 1 and x["attribute_name"] is not None . Looks like a pretty arbitrary stylistic decision. – SwissNavy Jan 27 at 11:39
I also encountered a situation in which it was even impossible to use a def(ined) function.
In this case, I really wanted to make a mapping which belonged to the class. Some objects in the mapping needed the same function. It would be illogical to put the a named function outside of the class. I have not found a way to refer to a method (staticmethod, classmethod or normal) from inside the class body. SomeClass does not exist yet when the code is run. So referring to it from the class isn't possible either.
- 1 You could refer to also_not_reachable in the mapping definition as SomeClass.also_not_reachable – Jan Matějka Sep 26, 2018 at 23:07
- 5 I don't know what point you're trying to make here. Every one of your function names is as reachable as f in both 2.7 and 3.5 for me – Eric Nov 12, 2018 at 3:15
- Nope, all the functions, except for the lambda function, are not reachable from within the Class body. You'll get a AttributeError: type object 'SomeClass' has no attribute '...' if you try to access one of those function in the some_mapping object. – simP Jun 26, 2019 at 9:44
- 3 @simP all of them are perfectly accessible. The ones with @staticmethod and @classmethod don't need an object, just SomeClass.also_not_reachable (although they need distinctive names). If you need to access them from class methods just use self.also_not_reachable – ababak Sep 16, 2019 at 11:34
- 2 @simP maybe you should rename your *not_reachable methods as not_as_easily_reachable_from_class_definition_as_a_lambda xD – Romain Vincent Mar 19, 2020 at 14:27
This works for me in a class, remove lambda expression and use def instead, changing this...
- Please add further details to expand on your answer, such as working code or documentation citations. – Community Bot Aug 29, 2021 at 11:18
- The OP never said his code doesn't work. It's only a warning, since it is a non-standard coding practice – Ankit Khettry Nov 1, 2021 at 15:32
Your Answer
Sign up or log in, post as a guest.
Required, but never shown
By clicking “Post Your Answer”, you agree to our terms of service , privacy policy and cookie policy
Not the answer you're looking for? Browse other questions tagged python lambda flake8 pep or ask your own question .
- The Overflow Blog
- How Intuit democratizes AI development across teams through reusability sponsored post
- The nature of simulating nature: A Q&A with IBM Quantum researcher Dr. Jamie...
- Featured on Meta
- We've added a "Necessary cookies only" option to the cookie consent popup
- Launching the CI/CD and R Collectives and community editing features for...
- Staging Ground Beta 1 Recap, and Reviewers needed for Beta 2
- The [amazon] tag is being burninated
Hot Network Questions
- Copyright issues when journal is defunct
- What video game is Charlie playing in Poker Face S01E07?
- Why are non-Western countries siding with China in the UN?
- How is Jesus "υἱὸς ὑψίστου κληθήσεται" (Luke 1:32 NAS28) different from a prophet (παιδίον, προφήτης ὑψίστου κληθήσῃ Luke 1:76 NAS28)?
- What is the purpose of this D-shaped ring at the base of the tongue on my hiking boots?
- Is it correct to use "the" before "materials used in making buildings are"?
- What is a word for the arcane equivalent of a monastery? A place where magic is studied and practiced?
- Jordan's line about intimate parties in The Great Gatsby?
- How do I connect these two faces together?
- Counting Letters in a String
- My code is GPL licensed, can I issue a license to have my code be distributed in a specific MIT licensed project?
- If a law is new but its interpretation is vague, can the courts directly ask the drafters the intent and official interpretation of their law?
- Redoing the align environment with a specific formatting
- Who owns code in a GitHub organization?
- Partner is not responding when their writing is needed in European project application
- How to react to a student’s panic attack in an oral exam?
- What sort of strategies would a medieval military use against a fantasy giant?
- Why is there a voltage on my HDMI and coaxial cables?
- Does Counterspell prevent from any further spells being cast on a given turn?
- Acidity of alcohols and basicity of amines
- What is the correct way to screw wall and ceiling drywalls?
- About an argument in Famine, Affluence and Morality
- Calculating probabilities from d6 dice pool (Degenesis rules for botches and triggers)
- Is it possible to create a concave light?
Your privacy
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy .
- No suggested jump to results
- Notifications
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
E731 do not assign a lambda expression, use a def #332
dreispt commented May 27, 2016
moylop260 commented May 27, 2016
Sorry, something went wrong.
lepistone commented May 27, 2016
Lepistone commented may 30, 2016, dreispt commented may 30, 2016.
No branches or pull requests
[2022 Day 11][Python] Question about: "Do not asign a lambda expression, use a def"

After solving day 11 I wanted to refactor my code.
I defined a "Monkey" class and my idea for the "operation" attribute for every "Monkey" was a lambda expressions which is parsed from the input.
After having fixed this bug for quite a long time I saw that Pycharm does not like my code and tells me "PEP: E731 do not assign a lambda expression, use a def"
Now I have the following questions:
What could be the pitfalls of assigning a lambda expression to a variable/ to my Monkey attribute?
Why is it against "PEP 8: E731" and is there any "better" solution that uses "def" and lambda expressions as pycharm suggests?

Yeah I wrote mine out of the gate with an operator, I just defined them in the class ez.
Figuring out part 2, not as ez.
PEP 8 is only a style guide. If you do f = lambda x: x*x , it would rather you do
def f(x): return x*x
If you need to assign the function with an = , then SomeClass.method = f after the function definition will still work.
About Community

subscribed puzzle solvers
coders furiously typing
Ranked by Size
- Documentation »
- Correctness »
- Assigning a lambda expression to a variable
- View page source
Assigning a lambda expression to a variable ¶
The sole advantage that a lambda expression has over a def is that the lambda can be anonymously embedded within a larger expression. If you are going to assign a name to a lambda , you are better off just defining it as a def .
From the PEP 8 Style Guide:
The first form means that the name of the resulting function object is specifically ‘f’ instead of the generic ‘<lambda>’. This is more useful for tracebacks and string representations in general. The use of the assignment statement eliminates the sole benefit a lambda expression can offer over an explicit def statement (i.e. that it can be embedded inside a larger expression)
Anti-pattern ¶
The following code assigns a lambda function which returns the double of its input to a variable. This is functionally identical to creating a def .
Best practice ¶
Use a def for named expressions ¶.
Refactor the lambda expression into a named def expression.
References ¶
- PEP 8 Style Guide - Programming Recommendations
- Stack Overflow - Do not assign a lambda expression

Python – E731 do not assign a lambda expression, use a def
lambda pep python
I get this pep8 warning whenever I use lambda expressions. Are lambda expressions not recommended? If not why?
Best Solution
The recommendation in PEP-8 you are running into is:
Always use a def statement instead of an assignment statement that binds a lambda expression directly to a name. Yes: def f(x): return 2*x No: f = lambda x: 2*x The first form means that the name of the resulting function object is specifically 'f' instead of the generic '<lambda>'. This is more useful for tracebacks and string representations in general. The use of the assignment statement eliminates the sole benefit a lambda expression can offer over an explicit def statement (i.e. that it can be embedded inside a larger expression)
Assigning lambdas to names basically just duplicates the functionality of def - and in general, it's best to do something a single way to avoid confusion and increase clarity.
The legitimate use case for lambda is where you want to use a function without assigning it, e.g:
In general, the main argument against doing this is that def statements will result in more lines of code. My main response to that would be: yes, and that is fine. Unless you are code golfing, minimising the number of lines isn't something you should be doing: go for clear over short.
Related Solutions
Python – calling a function of a module by using its name (a string).
Assuming module foo with method bar :
You could shorten lines 2 and 3 to:
if that makes more sense for your use case.
You can use getattr in this fashion on class instance bound methods, module-level methods, class methods... the list goes on.
Python – How to merge two dictionaries in a single expression (taking union of dictionaries)
How can I merge two Python dictionaries in a single expression?
For dictionaries x and y , z becomes a shallowly-merged dictionary with values from y replacing those from x .
In Python 3.9.0 or greater (released 17 October 2020): PEP-584 , discussed here , was implemented and provides the simplest method:
In Python 3.5 or greater:
In Python 2, (or 3.4 or lower) write a function:
Explanation
Say you have two dictionaries and you want to merge them into a new dictionary without altering the original dictionaries:
The desired result is to get a new dictionary ( z ) with the values merged, and the second dictionary's values overwriting those from the first.
A new syntax for this, proposed in PEP 448 and available as of Python 3.5 , is
And it is indeed a single expression.
Note that we can merge in with literal notation as well:
It is now showing as implemented in the release schedule for 3.5, PEP 478 , and it has now made its way into the What's New in Python 3.5 document.
However, since many organizations are still on Python 2, you may wish to do this in a backward-compatible way. The classically Pythonic way, available in Python 2 and Python 3.0-3.4, is to do this as a two-step process:
In both approaches, y will come second and its values will replace x 's values, thus b will point to 3 in our final result.
Not yet on Python 3.5, but want a single expression
If you are not yet on Python 3.5 or need to write backward-compatible code, and you want this in a single expression , the most performant while the correct approach is to put it in a function:
and then you have a single expression:
You can also make a function to merge an arbitrary number of dictionaries, from zero to a very large number:
This function will work in Python 2 and 3 for all dictionaries. e.g. given dictionaries a to g :
and key-value pairs in g will take precedence over dictionaries a to f , and so on.
Critiques of Other Answers
Don't use what you see in the formerly accepted answer:
In Python 2, you create two lists in memory for each dict, create a third list in memory with length equal to the length of the first two put together, and then discard all three lists to create the dict. In Python 3, this will fail because you're adding two dict_items objects together, not two lists -
and you would have to explicitly create them as lists, e.g. z = dict(list(x.items()) + list(y.items())) . This is a waste of resources and computation power.
Similarly, taking the union of items() in Python 3 ( viewitems() in Python 2.7) will also fail when values are unhashable objects (like lists, for example). Even if your values are hashable, since sets are semantically unordered, the behavior is undefined in regards to precedence. So don't do this:
This example demonstrates what happens when values are unhashable:
Here's an example where y should have precedence, but instead the value from x is retained due to the arbitrary order of sets:
Another hack you should not use:
This uses the dict constructor and is very fast and memory-efficient (even slightly more so than our two-step process) but unless you know precisely what is happening here (that is, the second dict is being passed as keyword arguments to the dict constructor), it's difficult to read, it's not the intended usage, and so it is not Pythonic.
Here's an example of the usage being remediated in django .
Dictionaries are intended to take hashable keys (e.g. frozenset s or tuples), but this method fails in Python 3 when keys are not strings.
From the mailing list , Guido van Rossum, the creator of the language, wrote:
I am fine with declaring dict({}, **{1:3}) illegal, since after all it is abuse of the ** mechanism.
Apparently dict(x, **y) is going around as "cool hack" for "call x.update(y) and return x". Personally, I find it more despicable than cool.
It is my understanding (as well as the understanding of the creator of the language ) that the intended usage for dict(**y) is for creating dictionaries for readability purposes, e.g.:
Response to comments
Despite what Guido says, dict(x, **y) is in line with the dict specification, which btw. works for both Python 2 and 3. The fact that this only works for string keys is a direct consequence of how keyword parameters work and not a short-coming of dict. Nor is using the ** operator in this place an abuse of the mechanism, in fact, ** was designed precisely to pass dictionaries as keywords.
Again, it doesn't work for 3 when keys are not strings. The implicit calling contract is that namespaces take ordinary dictionaries, while users must only pass keyword arguments that are strings. All other callables enforced it. dict broke this consistency in Python 2:
This inconsistency was bad given other implementations of Python (PyPy, Jython, IronPython). Thus it was fixed in Python 3, as this usage could be a breaking change.
I submit to you that it is malicious incompetence to intentionally write code that only works in one version of a language or that only works given certain arbitrary constraints.
More comments:
dict(x.items() + y.items()) is still the most readable solution for Python 2. Readability counts.
My response: merge_two_dicts(x, y) actually seems much clearer to me, if we're actually concerned about readability. And it is not forward compatible, as Python 2 is increasingly deprecated.
{**x, **y} does not seem to handle nested dictionaries. the contents of nested keys are simply overwritten, not merged [...] I ended up being burnt by these answers that do not merge recursively and I was surprised no one mentioned it. In my interpretation of the word "merging" these answers describe "updating one dict with another", and not merging.
Yes. I must refer you back to the question, which is asking for a shallow merge of two dictionaries, with the first's values being overwritten by the second's - in a single expression.
Assuming two dictionaries of dictionaries, one might recursively merge them in a single function, but you should be careful not to modify the dictionaries from either source, and the surest way to avoid that is to make a copy when assigning values. As keys must be hashable and are usually therefore immutable, it is pointless to copy them:
Coming up with contingencies for other value types is far beyond the scope of this question, so I will point you at my answer to the canonical question on a "Dictionaries of dictionaries merge" .
Less Performant But Correct Ad-hocs
These approaches are less performant, but they will provide correct behavior. They will be much less performant than copy and update or the new unpacking because they iterate through each key-value pair at a higher level of abstraction, but they do respect the order of precedence (latter dictionaries have precedence)
You can also chain the dictionaries manually inside a dict comprehension :
or in Python 2.6 (and perhaps as early as 2.4 when generator expressions were introduced):
itertools.chain will chain the iterators over the key-value pairs in the correct order:
Performance Analysis
I'm only going to do the performance analysis of the usages known to behave correctly. (Self-contained so you can copy and paste yourself.)
In Python 3.8.1, NixOS:
Resources on Dictionaries
- My explanation of Python's dictionary implementation , updated for 3.6.
- Answer on how to add new keys to a dictionary
- Mapping two lists into a dictionary
- The official Python docs on dictionaries
- The Dictionary Even Mightier - talk by Brandon Rhodes at Pycon 2017
- Modern Python Dictionaries, A Confluence of Great Ideas - talk by Raymond Hettinger at Pycon 2017
Related Question
- Python – Replacements for switch statement in Python
- C# – Retrieving Property name from lambda expression
- C# – Distinct() with lambda
- Python – List comprehension vs. lambda + filter
- C++ – a lambda expression in C++11
- C# – reason for C#’s reuse of the variable in a foreach
- Python – Why is “1000000000000000 in range(1000000000000001)” so fast in Python 3
note.nkmk.me
Lambda expressions in python.
In Python, functions are defined with def statements. You can also use lambda to create anonymous functions. You can use lambda expressions when you need to specify a function as an argument.
- 4. More Control Flow Tools - Lambda Expressions — Python 3.9.0 documentation
- 6. Expressions - Lambdas — Python 3.9.0 documentation
This article describes the following contents.
Basics of lambda expressions
Lambda expressions with if, pep8 recommends not naming lambda expressions, the key parameter of sorted() , sort() , max() , min(), map() , filter().
See the following article for the basics of functions in Python.
- Define and call functions in Python (def, return)
The function definition by the def statement and the corresponding lambda expression is as follows.
For convenience, in the above example, the lambda expression is assigned a name, but it is not recommended in PEP8 as described later.
The concrete example is as follows. You can also specify a default argument.
- Default arguments in Python
You cannot use multi-line statements in lambda expressions, but you can use conditional expressions.
- Conditional expressions in Python
If you assign a name to a lambda expression as in the previous examples, a warning may appear with the code checker.
PEP8 (Style Guide for Python Code) recommends that lambda expressions are meant to be used unnamed, and that def should be used when defining a function with a name.
Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier: PEP 8 -- Style Guide for Python Code | Python.org
Since it is only recommended but not prohibited, it can be executed without any error, even if you name lambda.
Examples of lambda expressions
The built-in function sorted() and the list method sort() and the built-in functions max() and min() have a key parameter.
- How to use a key parameter in Python (sorted, max, etc.)
You can specify a function applied to each element of the iterable object before each element is compared for key .
Take the built-in function sorted() as an example.
The list of strings is sorted alphabetically by default.
If you specify the built-in function len() that returns the number of characters in the argument key , it will be sorted according to the number of characters.
You can use a lambda expression to apply any function to each element and sort based on the result. For example, if you specify a lambda expression to get the second character in the argument key , it will be sorted alphabetically in the second character.
In map() , which applies a function to all elements of an iterable, and filter() , which extracts elements satisfying a condition, the first argument is a function (callable object) and the second argument is an iterable object such as a list.
- Apply a function to items of a list with map() in Python
- Filter (extract/remove) items of a list with filter() in Python
If you want to specify a function (callable object) as an argument, using a lambda expression is simpler than defining the function with a def statement.
Note that the same operation as map() and filter() can be written with list comprehensions and generator expressions. It is easier to write using list comprehensions and generator expressions in many cases.
- List comprehensions in Python
Specify a lambda expression that squares the value in the first argument. Note that map() returns an iterator instead of a list in Python3.
If you want to get a list, you can also write with list comprehension.
If you want to get an iterator, use a generator expression.
Specify a lambda expression that determines even numbers as True in the first argument.
filter() returns an iterator in Python3 like map() .
This can also be written with list comprehensions and generator expressions.
See the following article for details on extracting elements from a list.
- Extract, replace, convert elements of a list in Python
Related Categories
Related articles.
- Check Python version on command line and in script
- How to start enumerate() at 1 in Python
- Remove an item from a dictionary in Python (clear, pop, popitem, del)
- NumPy: Determine if ndarray is view or copy and if it shares memory
- pandas: Shuffle rows/elements of DataFrame/Series
- pandas: Get first/last n rows of DataFrame with head(), tail(), slice
- Concatenate images with Python, Pillow
- Copy and paste text to the clipboard with pyperclip in Python
- Set operations on multiple dictionary keys in Python
- pandas: Get and set options for display, data behavior, etc.
- Get quotient and remainder with divmod() in Python
- Update tuples in Python (Add, change, remove items in tuples)
- How to use range() in Python
- Generate square or circular thumbnail images with Python, Pillow
- Get the size of a file and directory in Python

IMAGES
VIDEO
COMMENTS
Always use a def statement instead of an assignment statement that binds a lambda expression directly to a name. Yes: def f(x): return 2*x. No:
Lambdas should not be assigned to a variable. Instead, they should be defined as functions. The primary reason for this is debugging.
Assigning a lambda to a variable is perfectly correct practice. It can be used, for example, to use a more readable alias for a longer
What could be the pitfalls of assigning a lambda expression to a variable/ to my Monkey attribute? Why is it against "PEP 8: E731" and is there
PYTHON : E731 do not assign a lambda expression, use a def [ Gift : Animated Search Engine : https://www.hows.tech/p/recommended.html ]
The sole advantage that a lambda expression has over a def is that the lambda can be anonymously embedded within a larger expression. If you are going to assign
Always use a def statement instead of an assignment statement that binds a lambda expression directly to a name. Yes: def f(x): return 2*x.
PEP8 (Style Guide for Python Code) recommends that lambda expressions are meant to be used unnamed, and that def should be used when defining a
identity = lambda x: x becomes def identity(x): return x though I think putting the return statement on a separate line is less awkward to read.
Know the differences between Python Lambda & Regular functions. ... E731 do not assign a lambda expression, use a def.