Python Lambda Functions – How to Use Anonymous Functions with Examples

Ashutosh Krishna

Lambda functions, also known as anonymous functions, are small, one-time-use functions in Python.

You can define them using the lambda keyword followed by the function's inputs, a colon, and the function's expression. The output of a lambda function is returned as the result of the expression, rather than a return statement.

The main purpose of lambda functions is to allow for the creation of small, throw-away functions that you can use in other parts of a program. This can be useful when you need to pass a simple function as an argument to another function, for example.

Syntax for creating lambda functions

Here is the syntax for creating a lambda function in Python:

Lambda Functions vs Named Functions Defined Using the def Keyword

When compared to named functions defined using the def keyword, lambda functions have some key differences.

Named functions can have multiple expressions and they use return statements. Lambda functions can only have one expression and the value of that expression is returned automatically.

Named functions can also be reused throughout a program, while lambda functions are used only once.

As you can see, the named function is defined using the def keyword, followed by the function name and its inputs in parentheses. The function body is indented, and the return statement is used to return the result of the expression.

Named functions can be called multiple times, making them more flexible than lambda functions for complex operations.

Here's the equivalent code using a named function defined with the lambda keyword:

How to Use Lambda Functions

This section covers the basics of how to create and use lambda functions, including their syntax and how to use them as arguments in higher-order functions such as map, filter, and reduce.

Additionally, this section explores how you can use lambda functions in sorting and in list comprehensions. By the end, you should have a foundational understanding of the basic uses of lambda functions.

How to use lambda functions as arguments in higher-order functions ( map , filter , reduce )

Lambda functions are often used as arguments in higher-order functions such as map , filter , and reduce . These functions allow you to apply a given operation to every element of a list or other iterable.

Here's an example of using a lambda function with the map function:

In this example, the lambda function takes one input x and returns the square of that value. The map function applies this operation to every element of the numbers list and returns a new list with the results.

Here's another example using the filter function:

In this example, the lambda function takes one input x and returns True if x is even, and False otherwise. The filter function applies this operation to every element of the numbers list and returns a new list with only the elements that returned True .

How to use lambda functions to return functions as values

You can also use lambda functions to return functions as values. For example:

In this example, the make_adder function takes one input x and returns a lambda function that takes one input y and returns the sum of x and y . The add5 variable is assigned the result of calling make_adder(5) , meaning it now references a lambda function that adds 5 to its input.

How to use lambda functions in sorting

You can also use lambda functions in sorting operations to specify custom sort orders. For example:

In this example, the lambda function takes one input x and returns -x , meaning that the sort order will be in descending order. The sorted function sorts the numbers list based on the values returned by the lambda function.

Limitations of Lambda Functions

While lambda functions are a convenient way to write short and simple functions, they have some limitations.

One of the main limitations is that lambda functions are limited to a single expression, meaning that they cannot contain multiple statements or complex control flow.

In addition, lambda functions cannot be referenced by name and can only be invoked when they are defined, which makes them less flexible than named functions.

Another limitation is that lambda functions do not have a name, which can make debugging more difficult and make it harder to understand the code.

In general, it's a good idea to use named functions for complex operations and only use lambda functions for short and simple operations.

Advanced Uses of Lambda Functions

This section covers how to use lambda functions with advanced functions such as reduce, filter, sorted, and key arguments. Additionally, this section provides information on using lambda functions to create anonymous functions for event handlers.

How to use lambda functions with reduce

The reduce function is a higher-order function that takes a binary function (a function that takes two arguments) and a list. It returns a single value that is the result of applying the binary function to the elements of the list in a cumulative way.

For example, to calculate the product of all elements in a list, you could use the following code:

In this example, the lambda function lambda x, y: x*y is used as the binary function in the reduce function. The reduce function starts by applying the binary function to the first two elements of the list, and then applies the result to the next element, and so on until it has processed all elements of the list.

How to use lambda functions with filter

The filter function is another higher-order function that takes a function and a list, and returns a new list that contains only the elements of the original list for which the function returns True .

For example, to filter out even numbers from a list, you could use the following code:

In this example, the lambda function lambda x: x % 2 == 0 is used as the function argument in the filter function. The filter function invokes this lambda function for each element in the numbers list and includes the element in the result list only if the lambda function returns True .

How to use lambda functions with the sorted function

The sorted function is a built-in function that sorts a list of elements. The sorted function can take an optional key argument, which is a function that takes an element of the list and returns a value that is used as the sort key.

For example, to sort a list of dictionaries by a specific key, you could use the following code:

In this example, the lambda function lambda x: x["age"] is used as the key argument in the sorted function. The sorted function uses this lambda function to extract the "age" value for each dictionary in the employees list and uses these values as the sort keys.

How to use lambda functions in the key argument of various functions

In addition to the sorted function, many other functions in Python can take a key argument, including the max , min , and sorted functions.

The key argument is a function that takes an element of the list and returns a value that is used as the sort key, as well as for comparison purposes in the case of the max and min functions.

For example, to find the employee with the highest salary in a list of employees, you could use the following code:

In this example, the lambda function lambda x: x["salary"] is used as the key argument in the max function. The max function uses this lambda function to extract the "salary" value for each employee in the employees list and uses these values to compare the employees and find the one with the highest salary.

How to use lambda functions to create anonymous functions for event handlers

You can also use lambda functions to create anonymous functions for event handlers in GUI programming or for other similar purposes.

For example, in the following code, a button click event is handled using a lambda function in Tkinter (a GUI programming toolkit for Python):

In this example, we use the lambda function lambda: print("Button clicked!") as the command argument of the Button widget in Tkinter. When the button is clicked, the lambda function is executed and the message "Button clicked!" is printed to the console.

This demonstrates the versatility and flexibility of lambda functions. You can use them in a variety of contexts where anonymous functions are required.

Best Practices for Using Lambda Functions

This section covers a range of best practices, including keeping lambda functions simple and easy to understand, avoiding complex expressions and statements, choosing the appropriate type of function for the task, and documenting lambda functions for better code readability.

We'll also highlight the importance of using descriptive variable names in lambda functions to improve the readability of your code.

Keep lambda functions simple and easy to understand

One of the best practices for using lambda functions is to keep them simple and easy to understand.

Lambda functions are intended to be small, anonymous, single-expression functions, and complex or multi-statement functions are better suited to be defined using the def keyword.

For example, the following lambda function is simple, easy to understand, and does exactly what it is intended to do:

Avoid complex expressions and statements in lambda functions

In addition to keeping lambda functions simple, it is also important to avoid complex expressions and statements in lambda functions.

Complex expressions and statements make the code harder to understand and maintain, and can lead to bugs.

For example, the following lambda function is too complex and difficult to understand:

In such cases, it is better to define a named function using the def keyword and provide a meaningful name for the function. This makes the code more readable and easier to maintain:

When to use lambda functions and when to use named functions

Lambda functions are best used in situations where you need a small, anonymous, single-expression function. They are not well suited for complex functions with multiple expressions and statements.

For example, a good use case for a lambda function is as an argument to a higher-order function such as map , filter , or reduce . A bad use case for a lambda function is a complex function with multiple expressions and statements.

In general, it is better to use named functions defined using the def keyword for functions that are complex, multi-statement, or are used multiple times in your code.

Document lambda functions for better code readability

Another best practice for using lambda functions is to document them for better code readability.

While lambda functions are often intended to be simple and easy to understand, it can still be helpful to provide a brief explanation of what the function does in the form of a docstring or a comment.

For example, the following lambda function is documented for better code readability:

Use descriptive variable names in lambda functions

Finally, it is important to use descriptive variable names in lambda functions, just as you would in any other function. Descriptive variable names make the code easier to understand and maintain.

For example, the following lambda function uses descriptive variable names:

By following these best practices, you can ensure that your lambda functions are clear, concise, and easy to understand, making your code more readable, maintainable, and error-free.

In this guide, we covered the basics of lambda functions in Python, including their definition and purpose, syntax, and basic and advanced usage in various applications.

We also discussed some best practices for using lambda functions, including keeping them simple and easy to understand, avoiding complex expressions and statements, choosing the appropriate type of function for the task, and documenting them for better code readability.

Lambda functions can be a powerful tool for writing concise, readable, and efficient code. But they have some limitations, such as being restricted to a single expression and having limited functionality compared to named functions. It's important to consider these limitations and choose the appropriate type of function for the task at hand.

In conclusion, this guide has provided an overview of lambda functions and their uses in Python, and I hope that it has been helpful in your journey to learn more about this topic. For further learning, you may want to explore the official Python documentation and practice using lambda functions in your own projects.

Visit my blog to read more articles like this. You may also choose to follow me on Twitter .

Application Developer at Thoughtworks India

If you read this far, thank the author to show them you care. Say Thanks

Learn to code for free. freeCodeCamp's open source curriculum has helped more than 40,000 people get jobs as developers. Get started

Python lambda function - with simple examples

Bashir Alam

August 1, 2021

Introduction to Python lambda

In Python and other programming languages, Lambda expressions have their roots in lambda calculus. Which was invented by Alozno Church. Lambda in Python are little anonymous functions , subject to a more restrictive but more concise syntax than regular Python functions. In this tutorial we will learn about python lambda functions and how they are related to regular functions. Moreover, we will also cover how to write lambda functions and how to use it properly.

Python lambda as Anonymous function

  • The  lambda  keyword creates an anonymous function within a Python expression.
  • However, the simple syntax of Python limits the body of lambda functions to be pure expressions .
  • In other words, the body cannot contain other Python statements such as  while ,  try , etc. Assignment with  =  is also a statement, so it cannot occur in a lambda.
  • The new assignment expression syntax using  := can be used, but if you need it, your lambda is probably too complicated and hard to read, and it should be refactored into a regular function using def .

Problems with Anonymous Functions

  • Beyond the Python-specific syntax constraints, anonymous functions have a serious drawback in any language.
  • Stack traces are easier to read when functions have names.
  • Anonymous functions are a handy shortcut, people have fun coding with them, but sometimes they get carried away—especially if the language and environment encourage deep nesting of anonymous functions, like JavaScript on Node.js do.
  • Lots of nested anonymous functions make debugging and error handling hard.
  • Asynchronous programming in Python is more structured, perhaps because the limited lambda syntax prevents its abuse and forces a more explicit approach.

Syntax of Python lambda function

A lambda expression creates a function object just like the def statement. Here is the syntax used to define a function using lambda:

Notice that we didn’t define a name to function , we just used keyword lambda and passed argument.

As already informed python lambda function only contains expressions and does not contain statements in the body. Statements like return , pass , assert , or raise will raise a syntaxError exception.

See the example below which raises a  syntax error when we try to use return in lambda.

Python lambda function - with simple examples

In contrast to a normal function, a Python lambda function is a single expression. Although, in the body of a lambda, you can spread the expression over several lines using parentheses or a multi-line string, it remains a single expression. See example below.

The example above returns odd when the argument is odd and returns even when we provide an even number as an argument. Although the code contains multiple lines, it still is counted as a single expression .

How to use Python lambda function

Here we will first take some examples of python functions and then will convert those into lambda functions. Let us start working with lambda by taking identity functions. Identity functions are those functions that return their arguments.

A very simple identity function is Python will be:

This function returns its argument whenever you call it. Now let us try to convert the same function in Lambda . See the python function which returns the square of the number.

If we try to write the same function in lambda, it will be something like this.

Moreover, we can also store the return value of lambda function in a variable   and later use that name to get access to the return value. See the example below which similar to the above example.

As in the definition we said that lambda can take multiple arguments . Let us now take an example to see how multiple arguments in lambda works.

Notice that multiple arguments in lambda are not inside any parentheses, they are just separated by commas .

We can pass arguments to the lambda function, immediately after defining it in the same line. See example below;

Compare Python lambda vs Python functions

You might wonder what is the main thing that differentiate between lambda and other python functions. Now in this section let us see how Python sees a function with a return single return statement and a lambda function.

First we have to import a python module named dis which exposes functions to analyse Python bytecode generated by the Python compiler.

Now we define the same logic using lambda function:

The bytecode interpreted by Python is the same for both functions . But you may notice that the naming is different: the function name is main for a function defined with def , whereas the Python lambda function is seen as lambda .

Passing arguments in python lambda

Like a normal function, lambda allows us to pass arguments in many ways. We can pass positional arguments, named arguments, variable lists, and keyword arguments as well.

Example-1: Pass arguments to lambda function

See the following examples to get familiar with different ways to pass arguments.

Example-2: Define variables inside lambda function

we can also define variables inside the lambda. See the example below where we defined variable b and equalize it to 3.

Example-3: Perform operation on the arguments

lambda also allows us to take as many arguments and return a function. See the example below where sum() function is returned.

Example-4: Handle return in lambda function

Moreover, we can take defined variable values as argument and return through a function as a return statement. See the example below.

Closure function in lambda

A closure function is a nested function which has access to a free variable from an encoding function that has finished its execution. There are mainly three main characteristics of closure function in Python.

  • First, it is a nested function.
  • Second, it has access to a free variable (a variable that is not bound in the local scope)  in outer space
  • Tthird characteristic is it is returned from the enclosing function.

The concepts of lambdas and closures are not necessarily related, although lambda functions can be closures in the same way that normal functions can also be closures. Here is an example of a closure function in python.

In a similar way lambda can also be used as a closure function. See the example below:

Evaluation time of lambda

Sometimes using lambda in a loop can behave unexpectedly. The following examples demonstrate the difference when using a regular function vs using a Python lambda. Let first take a regular function as an example.

In a normal function, x is evaluated at definition time, when the function is added to the list: fun.append(main(x)) .

Now, let us implement the same logic in lambda .

The unexpected result occurs because the free variable x , as implemented, is bound at the execution time of the lambda expression. The Python lambda function is a closure that captures x , a free variable bound at runtime. At runtime, while invoking the function f() the value of x is three.

We can overcome this issue by free variable at definition time. See the example below.

When to avoid using Python lambda function

In some cases we might face problems while using lambda. So, in such cases using a regular function would be the best option. In the following section, we will see some examples where the use of  lambda should be avoided.

Raising an exception in lambda

If we want to raise an exception, we should avoid using it with lambda. Rather using a regular function for exception handling will be the best option. See the following example, which gives you an error if you want to raise an exception with lambda.

Python lambda function - with simple examples

Python class and lambda

We can use lambda to write methods in Python but we should avoid using it. See the example below, which is legal Python code but exhibits unconventional python code relying on lambda. For example, instead of implementing __str__ as a regular function, it uses a lambda. Similarly, brand and year are properties also implemented with lambda functions, instead of regular functions or decorators:

This code gives error error E731 . We should avoid using lambda in python class and instead should use def .

Usage of Python Lambda

In the functional programming paradigm, some of the best known higher-order functions are  map ,  filter ,  reduce , and  apply .

The  apply  function was deprecated in Python 2.3 and removed in Python 3 because it’s no longer necessary. If you need to call a function with a dynamic set of arguments, you can write  fn(*args, **kwargs)  instead of  apply(fn, args, kwargs) .

The  map ,  filter , and  reduce higher-order functions are still around, but better alternatives are available for most of their use cases, as the next section shows.

Replacement of filter() function

The filter() is a python built-in function that takes a predicate as a first argument and an iterable as a second argument. It builds an iterator containing all the elements of the initial collection that satisfies the predicate function.

Here we try to find a list of factorials of odd numbers up to 5!, using both map and filter .

List comprehension does the same job, replacing map and filter, and making  lambda unnecessary .

Let us see one more example:

The same logic can be implemented in another way without using lambda . See the example below.

Replacement of map() function

The map() is a python built-in function that takes a function as the first argument and applies it to each of the elements of its second argument, an iterable. Examples of iterables include strings, lists and tuples. The map() returns an iterator corresponding to the transformed collection. For example, we can use map() to transform a list of strings to a new list with each string capitalized.

Now let's see how we can achieve the same logic without using lambda .

Lambda is also known as an anonymous function because of its anonymous behavior. It  can take any number of arguments but only one expression. The expression is evaluated and returned. Lambda functions can be used wherever function objects are required. In this tutorial we learned about lambda, their anonymous behavior and problems that lambda can cause in some cases. Moreover, we also learned about some cases where we should avoid using lambda.

Further Reading

lambda lambda in python History of lambda

He is a Computer Science graduate from the University of Central Asia, currently employed as a full-time Machine Learning Engineer at uExel. His expertise lies in OCR, text extraction, data preprocessing, and predictive models. You can reach out to him on his Linkedin or check his projects on GitHub page.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to [email protected]

Thank You for your support!!

Leave a Comment Cancel reply

Save my name and email in this browser for the next time I comment.

Notify me via e-mail if anyone answers my comment.

We try to offer easy-to-follow guides and tips on various topics such as Linux, Cloud Computing, Programming Languages, Ethical Hacking and much more.

Programming Languages

Exam certifications.

Certified Kubernetes Application Developer (CKAD)

CompTIA PenTest+ (PT0-002)

Red Hat EX407 (Ansible)

Hacker Rank Python

Privacy Policy

Trending Articles on Technical and Non Technical topics

  • Selected Reading
  • UPSC IAS Exams Notes
  • Developer's Best Practices
  • Questions and Answers
  • Effective Resume Writing
  • HR Interview Questions
  • Computer Glossary

Why can’t Python lambda expressions contain statements?

Yes, Python Lambda Expressions cannot contain statements. Before deep diving the reason, let us understand what is a Lambda, its expressions, and statements.

The Lambda expressions allow defining anonymous functions. A lambda function is an anonymous function i.e. a function without a name. Let us see the syntax −

The keyword lambda defines a lambda function. A lambda expression contains one or more arguments, but it can have only one expression.

Lambda Example

Let us see an example −

Sort a List by values from another list using Lambda

In this example, we will sort a list by values from another list i.e. the 2nd list will have the index in the order in which they are placed in sorted order −

Lambda Expressions cannot contain statements

We have seen two examples above wherein we have used Lambda expressions. Python lambda expressions cannot contain statements because Python’s syntactic framework can’t handle statements nested inside expressions.

Functions are already first-class objects in Python, and can be declared in a local scope. Therefore, the only advantage of using a lambda instead of a locally defined function is that you don’t need to invent a name for the function i.e. anonymous, but that’s just a local variable to which the function object is assigned!

AmitDiwan

Related Articles

  • Why we use lambda expressions in Java?
  • Lambda Expressions in C#
  • What are lambda expressions in C#?
  • Generalized Lambda Expressions in C++14
  • Are lambda expressions objects in Java?
  • Concurrent Programming Approach using Lambda Expressions
  • Why can’t raw strings (r-strings) end with a backslash in Python?
  • What are block lambda expressions in Java?
  • How to debug lambda expressions in Java?
  • Why can’t we override static methods in Java?
  • Differences between Lambda Expressions and Closures in Java?
  • Like plants why humans can’t prepare their own food?
  • Java Program to initialize a HashMap with Lambda Expressions
  • What are the characteristics of lambda expressions in Java?
  • How to implement the listeners using lambda expressions in Java?

Kickstart Your Career

Get certified by completing the course

  • Python Home
  • Documentation
  • Developer's Guide
  • Random Issue
  • Issues with patch
  • Easy issues

Google

  • Lost your login?
  • Committer List
  • Tracker Documentation
  • Tracker Development
  • Report Tracker Problem

python lambda cannot contain assignment

This issue tracker has been migrated to GitHub , and is currently read-only . For more information, see the GitHub FAQs in the Python's Developer Guide.

This issue has been migrated to GitHub: https://github.com/python/cpython/issues/33922

Created on 2001-02-14 08:45 by anonymous , last changed 2022-04-10 16:03 by admin . This issue is now closed .

  • Python »
  • 3.12.3 Documentation »
  • Python Frequently Asked Questions »
  • Design and History FAQ
  • Theme Auto Light Dark |

Design and History FAQ ¶

Why does python use indentation for grouping of statements ¶.

Guido van Rossum believes that using indentation for grouping is extremely elegant and contributes a lot to the clarity of the average Python program. Most people learn to love this feature after a while.

Since there are no begin/end brackets there cannot be a disagreement between grouping perceived by the parser and the human reader. Occasionally C programmers will encounter a fragment of code like this:

Only the x++ statement is executed if the condition is true, but the indentation leads many to believe otherwise. Even experienced C programmers will sometimes stare at it a long time wondering as to why y is being decremented even for x > y .

Because there are no begin/end brackets, Python is much less prone to coding-style conflicts. In C there are many different ways to place the braces. After becoming used to reading and writing code using a particular style, it is normal to feel somewhat uneasy when reading (or being required to write) in a different one.

Many coding styles place begin/end brackets on a line by themselves. This makes programs considerably longer and wastes valuable screen space, making it harder to get a good overview of a program. Ideally, a function should fit on one screen (say, 20–30 lines). 20 lines of Python can do a lot more work than 20 lines of C. This is not solely due to the lack of begin/end brackets – the lack of declarations and the high-level data types are also responsible – but the indentation-based syntax certainly helps.

Why am I getting strange results with simple arithmetic operations? ¶

See the next question.

Why are floating-point calculations so inaccurate? ¶

Users are often surprised by results like this:

and think it is a bug in Python. It’s not. This has little to do with Python, and much more to do with how the underlying platform handles floating-point numbers.

The float type in CPython uses a C double for storage. A float object’s value is stored in binary floating-point with a fixed precision (typically 53 bits) and Python uses C operations, which in turn rely on the hardware implementation in the processor, to perform floating-point operations. This means that as far as floating-point operations are concerned, Python behaves like many popular languages including C and Java.

Many numbers that can be written easily in decimal notation cannot be expressed exactly in binary floating-point. For example, after:

the value stored for x is a (very good) approximation to the decimal value 1.2 , but is not exactly equal to it. On a typical machine, the actual stored value is:

which is exactly:

The typical precision of 53 bits provides Python floats with 15–16 decimal digits of accuracy.

For a fuller explanation, please see the floating point arithmetic chapter in the Python tutorial.

Why are Python strings immutable? ¶

There are several advantages.

One is performance: knowing that a string is immutable means we can allocate space for it at creation time, and the storage requirements are fixed and unchanging. This is also one of the reasons for the distinction between tuples and lists.

Another advantage is that strings in Python are considered as “elemental” as numbers. No amount of activity will change the value 8 to anything else, and in Python, no amount of activity will change the string “eight” to anything else.

Why must ‘self’ be used explicitly in method definitions and calls? ¶

The idea was borrowed from Modula-3. It turns out to be very useful, for a variety of reasons.

First, it’s more obvious that you are using a method or instance attribute instead of a local variable. Reading self.x or self.meth() makes it absolutely clear that an instance variable or method is used even if you don’t know the class definition by heart. In C++, you can sort of tell by the lack of a local variable declaration (assuming globals are rare or easily recognizable) – but in Python, there are no local variable declarations, so you’d have to look up the class definition to be sure. Some C++ and Java coding standards call for instance attributes to have an m_ prefix, so this explicitness is still useful in those languages, too.

Second, it means that no special syntax is necessary if you want to explicitly reference or call the method from a particular class. In C++, if you want to use a method from a base class which is overridden in a derived class, you have to use the :: operator – in Python you can write baseclass.methodname(self, <argument list>) . This is particularly useful for __init__() methods, and in general in cases where a derived class method wants to extend the base class method of the same name and thus has to call the base class method somehow.

Finally, for instance variables it solves a syntactic problem with assignment: since local variables in Python are (by definition!) those variables to which a value is assigned in a function body (and that aren’t explicitly declared global), there has to be some way to tell the interpreter that an assignment was meant to assign to an instance variable instead of to a local variable, and it should preferably be syntactic (for efficiency reasons). C++ does this through declarations, but Python doesn’t have declarations and it would be a pity having to introduce them just for this purpose. Using the explicit self.var solves this nicely. Similarly, for using instance variables, having to write self.var means that references to unqualified names inside a method don’t have to search the instance’s directories. To put it another way, local variables and instance variables live in two different namespaces, and you need to tell Python which namespace to use.

Why can’t I use an assignment in an expression? ¶

Starting in Python 3.8, you can!

Assignment expressions using the walrus operator := assign a variable in an expression:

See PEP 572 for more information.

Why does Python use methods for some functionality (e.g. list.index()) but functions for other (e.g. len(list))? ¶

As Guido said:

(a) For some operations, prefix notation just reads better than postfix – prefix (and infix!) operations have a long tradition in mathematics which likes notations where the visuals help the mathematician thinking about a problem. Compare the easy with which we rewrite a formula like x*(a+b) into x*a + x*b to the clumsiness of doing the same thing using a raw OO notation. (b) When I read code that says len(x) I know that it is asking for the length of something. This tells me two things: the result is an integer, and the argument is some kind of container. To the contrary, when I read x.len(), I have to already know that x is some kind of container implementing an interface or inheriting from a class that has a standard len(). Witness the confusion we occasionally have when a class that is not implementing a mapping has a get() or keys() method, or something that isn’t a file has a write() method. — https://mail.python.org/pipermail/python-3000/2006-November/004643.html

Why is join() a string method instead of a list or tuple method? ¶

Strings became much more like other standard types starting in Python 1.6, when methods were added which give the same functionality that has always been available using the functions of the string module. Most of these new methods have been widely accepted, but the one which appears to make some programmers feel uncomfortable is:

which gives the result:

There are two common arguments against this usage.

The first runs along the lines of: “It looks really ugly using a method of a string literal (string constant)”, to which the answer is that it might, but a string literal is just a fixed value. If the methods are to be allowed on names bound to strings there is no logical reason to make them unavailable on literals.

The second objection is typically cast as: “I am really telling a sequence to join its members together with a string constant”. Sadly, you aren’t. For some reason there seems to be much less difficulty with having split() as a string method, since in that case it is easy to see that

is an instruction to a string literal to return the substrings delimited by the given separator (or, by default, arbitrary runs of white space).

join() is a string method because in using it you are telling the separator string to iterate over a sequence of strings and insert itself between adjacent elements. This method can be used with any argument which obeys the rules for sequence objects, including any new classes you might define yourself. Similar methods exist for bytes and bytearray objects.

How fast are exceptions? ¶

A try / except block is extremely efficient if no exceptions are raised. Actually catching an exception is expensive. In versions of Python prior to 2.0 it was common to use this idiom:

This only made sense when you expected the dict to have the key almost all the time. If that wasn’t the case, you coded it like this:

For this specific case, you could also use value = dict.setdefault(key, getvalue(key)) , but only if the getvalue() call is cheap enough because it is evaluated in all cases.

Why isn’t there a switch or case statement in Python? ¶

In general, structured switch statements execute one block of code when an expression has a particular value or set of values. Since Python 3.10 one can easily match literal values, or constants within a namespace, with a match ... case statement. An older alternative is a sequence of if... elif... elif... else .

For cases where you need to choose from a very large number of possibilities, you can create a dictionary mapping case values to functions to call. For example:

For calling methods on objects, you can simplify yet further by using the getattr() built-in to retrieve methods with a particular name:

It’s suggested that you use a prefix for the method names, such as visit_ in this example. Without such a prefix, if values are coming from an untrusted source, an attacker would be able to call any method on your object.

Imitating switch with fallthrough, as with C’s switch-case-default, is possible, much harder, and less needed.

Can’t you emulate threads in the interpreter instead of relying on an OS-specific thread implementation? ¶

Answer 1: Unfortunately, the interpreter pushes at least one C stack frame for each Python stack frame. Also, extensions can call back into Python at almost random moments. Therefore, a complete threads implementation requires thread support for C.

Answer 2: Fortunately, there is Stackless Python , which has a completely redesigned interpreter loop that avoids the C stack.

Why can’t lambda expressions contain statements? ¶

Python lambda expressions cannot contain statements because Python’s syntactic framework can’t handle statements nested inside expressions. However, in Python, this is not a serious problem. Unlike lambda forms in other languages, where they add functionality, Python lambdas are only a shorthand notation if you’re too lazy to define a function.

Functions are already first class objects in Python, and can be declared in a local scope. Therefore the only advantage of using a lambda instead of a locally defined function is that you don’t need to invent a name for the function – but that’s just a local variable to which the function object (which is exactly the same type of object that a lambda expression yields) is assigned!

Can Python be compiled to machine code, C or some other language? ¶

Cython compiles a modified version of Python with optional annotations into C extensions. Nuitka is an up-and-coming compiler of Python into C++ code, aiming to support the full Python language.

How does Python manage memory? ¶

The details of Python memory management depend on the implementation. The standard implementation of Python, CPython , uses reference counting to detect inaccessible objects, and another mechanism to collect reference cycles, periodically executing a cycle detection algorithm which looks for inaccessible cycles and deletes the objects involved. The gc module provides functions to perform a garbage collection, obtain debugging statistics, and tune the collector’s parameters.

Other implementations (such as Jython or PyPy ), however, can rely on a different mechanism such as a full-blown garbage collector. This difference can cause some subtle porting problems if your Python code depends on the behavior of the reference counting implementation.

In some Python implementations, the following code (which is fine in CPython) will probably run out of file descriptors:

Indeed, using CPython’s reference counting and destructor scheme, each new assignment to f closes the previous file. With a traditional GC, however, those file objects will only get collected (and closed) at varying and possibly long intervals.

If you want to write code that will work with any Python implementation, you should explicitly close the file or use the with statement; this will work regardless of memory management scheme:

Why doesn’t CPython use a more traditional garbage collection scheme? ¶

For one thing, this is not a C standard feature and hence it’s not portable. (Yes, we know about the Boehm GC library. It has bits of assembler code for most common platforms, not for all of them, and although it is mostly transparent, it isn’t completely transparent; patches are required to get Python to work with it.)

Traditional GC also becomes a problem when Python is embedded into other applications. While in a standalone Python it’s fine to replace the standard malloc() and free() with versions provided by the GC library, an application embedding Python may want to have its own substitute for malloc() and free() , and may not want Python’s. Right now, CPython works with anything that implements malloc() and free() properly.

Why isn’t all memory freed when CPython exits? ¶

Objects referenced from the global namespaces of Python modules are not always deallocated when Python exits. This may happen if there are circular references. There are also certain bits of memory that are allocated by the C library that are impossible to free (e.g. a tool like Purify will complain about these). Python is, however, aggressive about cleaning up memory on exit and does try to destroy every single object.

If you want to force Python to delete certain things on deallocation use the atexit module to run a function that will force those deletions.

Why are there separate tuple and list data types? ¶

Lists and tuples, while similar in many respects, are generally used in fundamentally different ways. Tuples can be thought of as being similar to Pascal records or C structs ; they’re small collections of related data which may be of different types which are operated on as a group. For example, a Cartesian coordinate is appropriately represented as a tuple of two or three numbers.

Lists, on the other hand, are more like arrays in other languages. They tend to hold a varying number of objects all of which have the same type and which are operated on one-by-one. For example, os.listdir('.') returns a list of strings representing the files in the current directory. Functions which operate on this output would generally not break if you added another file or two to the directory.

Tuples are immutable, meaning that once a tuple has been created, you can’t replace any of its elements with a new value. Lists are mutable, meaning that you can always change a list’s elements. Only immutable elements can be used as dictionary keys, and hence only tuples and not lists can be used as keys.

How are lists implemented in CPython? ¶

CPython’s lists are really variable-length arrays, not Lisp-style linked lists. The implementation uses a contiguous array of references to other objects, and keeps a pointer to this array and the array’s length in a list head structure.

This makes indexing a list a[i] an operation whose cost is independent of the size of the list or the value of the index.

When items are appended or inserted, the array of references is resized. Some cleverness is applied to improve the performance of appending items repeatedly; when the array must be grown, some extra space is allocated so the next few times don’t require an actual resize.

How are dictionaries implemented in CPython? ¶

CPython’s dictionaries are implemented as resizable hash tables. Compared to B-trees, this gives better performance for lookup (the most common operation by far) under most circumstances, and the implementation is simpler.

Dictionaries work by computing a hash code for each key stored in the dictionary using the hash() built-in function. The hash code varies widely depending on the key and a per-process seed; for example, 'Python' could hash to -539294296 while 'python' , a string that differs by a single bit, could hash to 1142331976 . The hash code is then used to calculate a location in an internal array where the value will be stored. Assuming that you’re storing keys that all have different hash values, this means that dictionaries take constant time – O (1), in Big-O notation – to retrieve a key.

Why must dictionary keys be immutable? ¶

The hash table implementation of dictionaries uses a hash value calculated from the key value to find the key. If the key were a mutable object, its value could change, and thus its hash could also change. But since whoever changes the key object can’t tell that it was being used as a dictionary key, it can’t move the entry around in the dictionary. Then, when you try to look up the same object in the dictionary it won’t be found because its hash value is different. If you tried to look up the old value it wouldn’t be found either, because the value of the object found in that hash bin would be different.

If you want a dictionary indexed with a list, simply convert the list to a tuple first; the function tuple(L) creates a tuple with the same entries as the list L . Tuples are immutable and can therefore be used as dictionary keys.

Some unacceptable solutions that have been proposed:

Hash lists by their address (object ID). This doesn’t work because if you construct a new list with the same value it won’t be found; e.g.:

would raise a KeyError exception because the id of the [1, 2] used in the second line differs from that in the first line. In other words, dictionary keys should be compared using == , not using is .

Make a copy when using a list as a key. This doesn’t work because the list, being a mutable object, could contain a reference to itself, and then the copying code would run into an infinite loop.

Allow lists as keys but tell the user not to modify them. This would allow a class of hard-to-track bugs in programs when you forgot or modified a list by accident. It also invalidates an important invariant of dictionaries: every value in d.keys() is usable as a key of the dictionary.

Mark lists as read-only once they are used as a dictionary key. The problem is that it’s not just the top-level object that could change its value; you could use a tuple containing a list as a key. Entering anything as a key into a dictionary would require marking all objects reachable from there as read-only – and again, self-referential objects could cause an infinite loop.

There is a trick to get around this if you need to, but use it at your own risk: You can wrap a mutable structure inside a class instance which has both a __eq__() and a __hash__() method. You must then make sure that the hash value for all such wrapper objects that reside in a dictionary (or other hash based structure), remain fixed while the object is in the dictionary (or other structure).

Note that the hash computation is complicated by the possibility that some members of the list may be unhashable and also by the possibility of arithmetic overflow.

Furthermore it must always be the case that if o1 == o2 (ie o1.__eq__(o2) is True ) then hash(o1) == hash(o2) (ie, o1.__hash__() == o2.__hash__() ), regardless of whether the object is in a dictionary or not. If you fail to meet these restrictions dictionaries and other hash based structures will misbehave.

In the case of ListWrapper , whenever the wrapper object is in a dictionary the wrapped list must not change to avoid anomalies. Don’t do this unless you are prepared to think hard about the requirements and the consequences of not meeting them correctly. Consider yourself warned.

Why doesn’t list.sort() return the sorted list? ¶

In situations where performance matters, making a copy of the list just to sort it would be wasteful. Therefore, list.sort() sorts the list in place. In order to remind you of that fact, it does not return the sorted list. This way, you won’t be fooled into accidentally overwriting a list when you need a sorted copy but also need to keep the unsorted version around.

If you want to return a new list, use the built-in sorted() function instead. This function creates a new list from a provided iterable, sorts it and returns it. For example, here’s how to iterate over the keys of a dictionary in sorted order:

How do you specify and enforce an interface spec in Python? ¶

An interface specification for a module as provided by languages such as C++ and Java describes the prototypes for the methods and functions of the module. Many feel that compile-time enforcement of interface specifications helps in the construction of large programs.

Python 2.6 adds an abc module that lets you define Abstract Base Classes (ABCs). You can then use isinstance() and issubclass() to check whether an instance or a class implements a particular ABC. The collections.abc module defines a set of useful ABCs such as Iterable , Container , and MutableMapping .

For Python, many of the advantages of interface specifications can be obtained by an appropriate test discipline for components.

A good test suite for a module can both provide a regression test and serve as a module interface specification and a set of examples. Many Python modules can be run as a script to provide a simple “self test.” Even modules which use complex external interfaces can often be tested in isolation using trivial “stub” emulations of the external interface. The doctest and unittest modules or third-party test frameworks can be used to construct exhaustive test suites that exercise every line of code in a module.

An appropriate testing discipline can help build large complex applications in Python as well as having interface specifications would. In fact, it can be better because an interface specification cannot test certain properties of a program. For example, the list.append() method is expected to add new elements to the end of some internal list; an interface specification cannot test that your list.append() implementation will actually do this correctly, but it’s trivial to check this property in a test suite.

Writing test suites is very helpful, and you might want to design your code to make it easily tested. One increasingly popular technique, test-driven development, calls for writing parts of the test suite first, before you write any of the actual code. Of course Python allows you to be sloppy and not write test cases at all.

Why is there no goto? ¶

In the 1970s people realized that unrestricted goto could lead to messy “spaghetti” code that was hard to understand and revise. In a high-level language, it is also unneeded as long as there are ways to branch (in Python, with if statements and or , and , and if / else expressions) and loop (with while and for statements, possibly containing continue and break ).

One can also use exceptions to provide a “structured goto” that works even across function calls. Many feel that exceptions can conveniently emulate all reasonable uses of the go or goto constructs of C, Fortran, and other languages. For example:

This doesn’t allow you to jump into the middle of a loop, but that’s usually considered an abuse of goto anyway. Use sparingly.

Why can’t raw strings (r-strings) end with a backslash? ¶

More precisely, they can’t end with an odd number of backslashes: the unpaired backslash at the end escapes the closing quote character, leaving an unterminated string.

Raw strings were designed to ease creating input for processors (chiefly regular expression engines) that want to do their own backslash escape processing. Such processors consider an unmatched trailing backslash to be an error anyway, so raw strings disallow that. In return, they allow you to pass on the string quote character by escaping it with a backslash. These rules work well when r-strings are used for their intended purpose.

If you’re trying to build Windows pathnames, note that all Windows system calls accept forward slashes too:

If you’re trying to build a pathname for a DOS command, try e.g. one of

Why doesn’t Python have a “with” statement for attribute assignments? ¶

Python has a with statement that wraps the execution of a block, calling code on the entrance and exit from the block. Some languages have a construct that looks like this:

In Python, such a construct would be ambiguous.

Other languages, such as Object Pascal, Delphi, and C++, use static types, so it’s possible to know, in an unambiguous way, what member is being assigned to. This is the main point of static typing – the compiler always knows the scope of every variable at compile time.

Python uses dynamic types. It is impossible to know in advance which attribute will be referenced at runtime. Member attributes may be added or removed from objects on the fly. This makes it impossible to know, from a simple reading, what attribute is being referenced: a local one, a global one, or a member attribute?

For instance, take the following incomplete snippet:

The snippet assumes that a must have a member attribute called x . However, there is nothing in Python that tells the interpreter this. What should happen if a is, let us say, an integer? If there is a global variable named x , will it be used inside the with block? As you see, the dynamic nature of Python makes such choices much harder.

The primary benefit of with and similar language features (reduction of code volume) can, however, easily be achieved in Python by assignment. Instead of:

write this:

This also has the side-effect of increasing execution speed because name bindings are resolved at run-time in Python, and the second version only needs to perform the resolution once.

Similar proposals that would introduce syntax to further reduce code volume, such as using a ‘leading dot’, have been rejected in favour of explicitness (see https://mail.python.org/pipermail/python-ideas/2016-May/040070.html ).

Why don’t generators support the with statement? ¶

For technical reasons, a generator used directly as a context manager would not work correctly. When, as is most common, a generator is used as an iterator run to completion, no closing is needed. When it is, wrap it as contextlib.closing(generator) in the with statement.

Why are colons required for the if/while/def/class statements? ¶

The colon is required primarily to enhance readability (one of the results of the experimental ABC language). Consider this:

Notice how the second one is slightly easier to read. Notice further how a colon sets off the example in this FAQ answer; it’s a standard usage in English.

Another minor reason is that the colon makes it easier for editors with syntax highlighting; they can look for colons to decide when indentation needs to be increased instead of having to do a more elaborate parsing of the program text.

Why does Python allow commas at the end of lists and tuples? ¶

Python lets you add a trailing comma at the end of lists, tuples, and dictionaries:

There are several reasons to allow this.

When you have a literal value for a list, tuple, or dictionary spread across multiple lines, it’s easier to add more elements because you don’t have to remember to add a comma to the previous line. The lines can also be reordered without creating a syntax error.

Accidentally omitting the comma can lead to errors that are hard to diagnose. For example:

This list looks like it has four elements, but it actually contains three: “fee”, “fiefoo” and “fum”. Always adding the comma avoids this source of error.

Allowing the trailing comma may also make programmatic code generation easier.

Table of Contents

  • Why does Python use indentation for grouping of statements?
  • Why am I getting strange results with simple arithmetic operations?
  • Why are floating-point calculations so inaccurate?
  • Why are Python strings immutable?
  • Why must ‘self’ be used explicitly in method definitions and calls?
  • Why can’t I use an assignment in an expression?
  • Why does Python use methods for some functionality (e.g. list.index()) but functions for other (e.g. len(list))?
  • Why is join() a string method instead of a list or tuple method?
  • How fast are exceptions?
  • Why isn’t there a switch or case statement in Python?
  • Can’t you emulate threads in the interpreter instead of relying on an OS-specific thread implementation?
  • Why can’t lambda expressions contain statements?
  • Can Python be compiled to machine code, C or some other language?
  • How does Python manage memory?
  • Why doesn’t CPython use a more traditional garbage collection scheme?
  • Why isn’t all memory freed when CPython exits?
  • Why are there separate tuple and list data types?
  • How are lists implemented in CPython?
  • How are dictionaries implemented in CPython?
  • Why must dictionary keys be immutable?
  • Why doesn’t list.sort() return the sorted list?
  • How do you specify and enforce an interface spec in Python?
  • Why is there no goto?
  • Why can’t raw strings (r-strings) end with a backslash?
  • Why doesn’t Python have a “with” statement for attribute assignments?
  • Why don’t generators support the with statement?
  • Why are colons required for the if/while/def/class statements?
  • Why does Python allow commas at the end of lists and tuples?

Previous topic

Programming FAQ

Library and Extension FAQ

  • Report a Bug
  • Show Source

Search code, repositories, users, issues, pull requests...

Provide feedback.

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly.

To see all available qualifiers, see our documentation .

  • 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

error message confusing for assignment in lambda #33922

@tim-one

anonymous mannequin commented Feb 14, 2001

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

GitHub fields:

bugs.python.org fields:

The text was updated successfully, but these errors were encountered:

@nobody

nobody mannequin commented Feb 14, 2001

Sorry, something went wrong.

@anonymous

gvanrossum commented Feb 14, 2001

@tim-one

tim-one commented Feb 18, 2001

@ezio-melotti

No branches or pull requests

@gvanrossum

python - 为什么在 Python 的 `lambda` 表达式中不允许赋值?

标签 python lambda python-internals side-effects

这不是 Assignment inside lambda expression in Python 的副本,也就是说,我 不是 问如何欺骗 Python 在 lambda 表达式中赋值。

我有一些 λ 演算背景。考虑以下代码,它 看起来 Python 非常愿意在 lambda 中执行副作用 表达式:

但是如果我取消注释这些行

为什么不呢? 这背后更深层的原因是什么?

正如代码所展示的,它不可能是关于“纯度”的 功能意义。

我能想到的唯一解释是赋值不 返回任何东西,甚至 None 。但这听起来很蹩脚,而且会 易于修复(一种方法:使 lambda 表达式返回 None 如果 body 是一个声明)。

因为它是这样定义的(我想知道为什么它是这样定义的)。

因为它在语法中(见上文)。

如果您需要语句,请使用 def (我没有问如何获取 语句转换为函数)。

“这会改变语法/语言/语义”作为答案是可以的,如果你能想出这样的改变的例子,以及为什么它会不好。

lambda 存在的全部原因是它是一个表达式。 1 如果您想要类似于 lambda 但只是一个语句的东西,那只是 def .

Python 表达式不能包含语句。事实上,这是该语言的基础,Python 从该决定中获得了很多好处。这就是流程控制的缩进有效而不是像许多其他尝试(如 CoffeeScript)那样笨拙的原因。这就是您可以通过浏览每行中的第一个对象来读取状态更改的原因。对于编译器和人类读者来说,这甚至是该语言易于解析的部分原因。 2

改变 Python 以某种方式“逃避”语句-表达式的鸿沟,除非以一种非常谨慎和有限的方式进行,否则会将其变成一种完全不同的语言,并且不再具有许多导致的好处人们首先选择 Python。

将 Python 更改为大多数语句表达式(例如,Ruby)会再次将其变成一种完全不同的语言,而没有 Python 当前的优势。

如果 Python 确实 进行了这些更改中的任何一个,那么就不再有使用 lambda 的理由了; 2,3 你可以在表达式中使用 def 语句。

如何更改 Python 来代替赋值表达式?好吧,很明显,这会打破“您可以通过浏览每行中的第一个对象来读取状态变化”。虽然 Guido 通常关注的事实是 if spam=eggs 是一个错误而不是有用的东西。

Python 确实为您提供了在需要时解决该问题的方法,例如 setattr 甚至在 globals() 上显式调用 __setitem__ , 并不意味着它应该有直接的语法支持。很少需要的东西不值得语法糖——对于足够不寻常的东西更是如此,当它实际完成时应该引起人们的注意和/或警告。

1。我不知道这是否是 Guido 最初在 Python 1.0 中添加 lambda 时的理解。但这绝对是 lambda 未在 Python 3.0 中删除的原因。

2。事实上,Guido 多次建议允许人类可以在头脑中运行的 LL(1) 解析器是语言基于语句的充分理由,以至于其他好处甚至不需要讨论. I wrote about this a few years ago 如果有人感兴趣的话。

3。如果你想知道为什么这么多语言 确实 有一个 lambda 表达式,尽管已经有了 def :在许多语言中,从C++到Ruby,函数不是可以传递的一流对象,因此他们不得不发明第二个东西,它是一流的但像函数一样工作。在其他情况下,从 Smalltalk 到 Java,函数甚至 不存在 ,只有方法,所以他们不得不再次发明另一种东西,它不是方法但可以像方法一样工作。 Python 没有这些问题。

4。一些语言,如 C# 和 JavaScript,实际上具有完美工作的内联函数定义,但添加了某种 lambda 语法作为纯语法糖,使其更简洁、更少样板。这在 Python 中实际上可能值得做(尽管到目前为止,对良好语法的每一次尝试都失败了),但它不会是当前的 lambda 语法,它几乎和 一样冗长def .

关于python - 为什么在 Python 的 `lambda` 表达式中不允许赋值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50090868/

上一篇: python - 使用 paramiko 检查远程主机上是否存在路径

下一篇: python - 使用 pyarrow 如何附加到 parquet 文件?.

python - 在numpy数组中查找最大元素比较的索引

python - 在 Pandas 中合并 Dataframe block

python - Lambda 上的 MySQL 连接器产生无法导入模块 'myapp' : No module named 'mysql'

python - 是否有可能 "hack"Python 的打印功能?

python - 将一系列整数转换为字符串 - 为什么应用比 astype 快得​​多?

python - Python 中的平均函数

python - 对数据存储的分层查询

c# - 从异步 lambda Action 转换为 Func<Task>?

C# 使用 lambda 获取列值并读取代码后面的值

python - python @properties 如何以及何时评估

©2024 IT工具网   联系我们

Python Forum

  • View Active Threads
  • View Today's Posts
  • View New Posts
  • My Discussions
  • Unanswered Posts
  • Unread Posts
  • Active Threads
  • Mark all forums read
  • Member List
  • Interpreter

How do I make an assignment inside lambda function?

  • Python Forum
  • Python Coding
  • General Coding Help
  • 0 Vote(s) - 0 Average
  • View a Printable Version

User Panel Messages

Announcements.

python lambda cannot contain assignment

Login to Python Forum

Python Enhancement Proposals

  • Python »
  • PEP Index »

PEP 572 – Assignment Expressions

The importance of real code, exceptional cases, scope of the target, relative precedence of :=, change to evaluation order, differences between assignment expressions and assignment statements, specification changes during implementation, _pydecimal.py, datetime.py, sysconfig.py, simplifying list comprehensions, capturing condition values, changing the scope rules for comprehensions, alternative spellings, special-casing conditional statements, special-casing comprehensions, lowering operator precedence, allowing commas to the right, always requiring parentheses, why not just turn existing assignment into an expression, with assignment expressions, why bother with assignment statements, why not use a sublocal scope and prevent namespace pollution, style guide recommendations, acknowledgements, a numeric example, appendix b: rough code translations for comprehensions, appendix c: no changes to scope semantics.

This is a proposal for creating a way to assign to variables within an expression using the notation NAME := expr .

As part of this change, there is also an update to dictionary comprehension evaluation order to ensure key expressions are executed before value expressions (allowing the key to be bound to a name and then re-used as part of calculating the corresponding value).

During discussion of this PEP, the operator became informally known as “the walrus operator”. The construct’s formal name is “Assignment Expressions” (as per the PEP title), but they may also be referred to as “Named Expressions” (e.g. the CPython reference implementation uses that name internally).

Naming the result of an expression is an important part of programming, allowing a descriptive name to be used in place of a longer expression, and permitting reuse. Currently, this feature is available only in statement form, making it unavailable in list comprehensions and other expression contexts.

Additionally, naming sub-parts of a large expression can assist an interactive debugger, providing useful display hooks and partial results. Without a way to capture sub-expressions inline, this would require refactoring of the original code; with assignment expressions, this merely requires the insertion of a few name := markers. Removing the need to refactor reduces the likelihood that the code be inadvertently changed as part of debugging (a common cause of Heisenbugs), and is easier to dictate to another programmer.

During the development of this PEP many people (supporters and critics both) have had a tendency to focus on toy examples on the one hand, and on overly complex examples on the other.

The danger of toy examples is twofold: they are often too abstract to make anyone go “ooh, that’s compelling”, and they are easily refuted with “I would never write it that way anyway”.

The danger of overly complex examples is that they provide a convenient strawman for critics of the proposal to shoot down (“that’s obfuscated”).

Yet there is some use for both extremely simple and extremely complex examples: they are helpful to clarify the intended semantics. Therefore, there will be some of each below.

However, in order to be compelling , examples should be rooted in real code, i.e. code that was written without any thought of this PEP, as part of a useful application, however large or small. Tim Peters has been extremely helpful by going over his own personal code repository and picking examples of code he had written that (in his view) would have been clearer if rewritten with (sparing) use of assignment expressions. His conclusion: the current proposal would have allowed a modest but clear improvement in quite a few bits of code.

Another use of real code is to observe indirectly how much value programmers place on compactness. Guido van Rossum searched through a Dropbox code base and discovered some evidence that programmers value writing fewer lines over shorter lines.

Case in point: Guido found several examples where a programmer repeated a subexpression, slowing down the program, in order to save one line of code, e.g. instead of writing:

they would write:

Another example illustrates that programmers sometimes do more work to save an extra level of indentation:

This code tries to match pattern2 even if pattern1 has a match (in which case the match on pattern2 is never used). The more efficient rewrite would have been:

Syntax and semantics

In most contexts where arbitrary Python expressions can be used, a named expression can appear. This is of the form NAME := expr where expr is any valid Python expression other than an unparenthesized tuple, and NAME is an identifier.

The value of such a named expression is the same as the incorporated expression, with the additional side-effect that the target is assigned that value:

There are a few places where assignment expressions are not allowed, in order to avoid ambiguities or user confusion:

This rule is included to simplify the choice for the user between an assignment statement and an assignment expression – there is no syntactic position where both are valid.

Again, this rule is included to avoid two visually similar ways of saying the same thing.

This rule is included to disallow excessively confusing code, and because parsing keyword arguments is complex enough already.

This rule is included to discourage side effects in a position whose exact semantics are already confusing to many users (cf. the common style recommendation against mutable default values), and also to echo the similar prohibition in calls (the previous bullet).

The reasoning here is similar to the two previous cases; this ungrouped assortment of symbols and operators composed of : and = is hard to read correctly.

This allows lambda to always bind less tightly than := ; having a name binding at the top level inside a lambda function is unlikely to be of value, as there is no way to make use of it. In cases where the name will be used more than once, the expression is likely to need parenthesizing anyway, so this prohibition will rarely affect code.

This shows that what looks like an assignment operator in an f-string is not always an assignment operator. The f-string parser uses : to indicate formatting options. To preserve backwards compatibility, assignment operator usage inside of f-strings must be parenthesized. As noted above, this usage of the assignment operator is not recommended.

An assignment expression does not introduce a new scope. In most cases the scope in which the target will be bound is self-explanatory: it is the current scope. If this scope contains a nonlocal or global declaration for the target, the assignment expression honors that. A lambda (being an explicit, if anonymous, function definition) counts as a scope for this purpose.

There is one special case: an assignment expression occurring in a list, set or dict comprehension or in a generator expression (below collectively referred to as “comprehensions”) binds the target in the containing scope, honoring a nonlocal or global declaration for the target in that scope, if one exists. For the purpose of this rule the containing scope of a nested comprehension is the scope that contains the outermost comprehension. A lambda counts as a containing scope.

The motivation for this special case is twofold. First, it allows us to conveniently capture a “witness” for an any() expression, or a counterexample for all() , for example:

Second, it allows a compact way of updating mutable state from a comprehension, for example:

However, an assignment expression target name cannot be the same as a for -target name appearing in any comprehension containing the assignment expression. The latter names are local to the comprehension in which they appear, so it would be contradictory for a contained use of the same name to refer to the scope containing the outermost comprehension instead.

For example, [i := i+1 for i in range(5)] is invalid: the for i part establishes that i is local to the comprehension, but the i := part insists that i is not local to the comprehension. The same reason makes these examples invalid too:

While it’s technically possible to assign consistent semantics to these cases, it’s difficult to determine whether those semantics actually make sense in the absence of real use cases. Accordingly, the reference implementation [1] will ensure that such cases raise SyntaxError , rather than executing with implementation defined behaviour.

This restriction applies even if the assignment expression is never executed:

For the comprehension body (the part before the first “for” keyword) and the filter expression (the part after “if” and before any nested “for”), this restriction applies solely to target names that are also used as iteration variables in the comprehension. Lambda expressions appearing in these positions introduce a new explicit function scope, and hence may use assignment expressions with no additional restrictions.

Due to design constraints in the reference implementation (the symbol table analyser cannot easily detect when names are re-used between the leftmost comprehension iterable expression and the rest of the comprehension), named expressions are disallowed entirely as part of comprehension iterable expressions (the part after each “in”, and before any subsequent “if” or “for” keyword):

A further exception applies when an assignment expression occurs in a comprehension whose containing scope is a class scope. If the rules above were to result in the target being assigned in that class’s scope, the assignment expression is expressly invalid. This case also raises SyntaxError :

(The reason for the latter exception is the implicit function scope created for comprehensions – there is currently no runtime mechanism for a function to refer to a variable in the containing class scope, and we do not want to add such a mechanism. If this issue ever gets resolved this special case may be removed from the specification of assignment expressions. Note that the problem already exists for using a variable defined in the class scope from a comprehension.)

See Appendix B for some examples of how the rules for targets in comprehensions translate to equivalent code.

The := operator groups more tightly than a comma in all syntactic positions where it is legal, but less tightly than all other operators, including or , and , not , and conditional expressions ( A if C else B ). As follows from section “Exceptional cases” above, it is never allowed at the same level as = . In case a different grouping is desired, parentheses should be used.

The := operator may be used directly in a positional function call argument; however it is invalid directly in a keyword argument.

Some examples to clarify what’s technically valid or invalid:

Most of the “valid” examples above are not recommended, since human readers of Python source code who are quickly glancing at some code may miss the distinction. But simple cases are not objectionable:

This PEP recommends always putting spaces around := , similar to PEP 8 ’s recommendation for = when used for assignment, whereas the latter disallows spaces around = used for keyword arguments.)

In order to have precisely defined semantics, the proposal requires evaluation order to be well-defined. This is technically not a new requirement, as function calls may already have side effects. Python already has a rule that subexpressions are generally evaluated from left to right. However, assignment expressions make these side effects more visible, and we propose a single change to the current evaluation order:

  • In a dict comprehension {X: Y for ...} , Y is currently evaluated before X . We propose to change this so that X is evaluated before Y . (In a dict display like {X: Y} this is already the case, and also in dict((X, Y) for ...) which should clearly be equivalent to the dict comprehension.)

Most importantly, since := is an expression, it can be used in contexts where statements are illegal, including lambda functions and comprehensions.

Conversely, assignment expressions don’t support the advanced features found in assignment statements:

  • Multiple targets are not directly supported: x = y = z = 0 # Equivalent: (z := (y := (x := 0)))
  • Single assignment targets other than a single NAME are not supported: # No equivalent a [ i ] = x self . rest = []
  • Priority around commas is different: x = 1 , 2 # Sets x to (1, 2) ( x := 1 , 2 ) # Sets x to 1
  • Iterable packing and unpacking (both regular or extended forms) are not supported: # Equivalent needs extra parentheses loc = x , y # Use (loc := (x, y)) info = name , phone , * rest # Use (info := (name, phone, *rest)) # No equivalent px , py , pz = position name , phone , email , * other_info = contact
  • Inline type annotations are not supported: # Closest equivalent is "p: Optional[int]" as a separate declaration p : Optional [ int ] = None
  • Augmented assignment is not supported: total += tax # Equivalent: (total := total + tax)

The following changes have been made based on implementation experience and additional review after the PEP was first accepted and before Python 3.8 was released:

  • for consistency with other similar exceptions, and to avoid locking in an exception name that is not necessarily going to improve clarity for end users, the originally proposed TargetScopeError subclass of SyntaxError was dropped in favour of just raising SyntaxError directly. [3]
  • due to a limitation in CPython’s symbol table analysis process, the reference implementation raises SyntaxError for all uses of named expressions inside comprehension iterable expressions, rather than only raising them when the named expression target conflicts with one of the iteration variables in the comprehension. This could be revisited given sufficiently compelling examples, but the extra complexity needed to implement the more selective restriction doesn’t seem worthwhile for purely hypothetical use cases.

Examples from the Python standard library

env_base is only used on these lines, putting its assignment on the if moves it as the “header” of the block.

  • Current: env_base = os . environ . get ( "PYTHONUSERBASE" , None ) if env_base : return env_base
  • Improved: if env_base := os . environ . get ( "PYTHONUSERBASE" , None ): return env_base

Avoid nested if and remove one indentation level.

  • Current: if self . _is_special : ans = self . _check_nans ( context = context ) if ans : return ans
  • Improved: if self . _is_special and ( ans := self . _check_nans ( context = context )): return ans

Code looks more regular and avoid multiple nested if. (See Appendix A for the origin of this example.)

  • Current: reductor = dispatch_table . get ( cls ) if reductor : rv = reductor ( x ) else : reductor = getattr ( x , "__reduce_ex__" , None ) if reductor : rv = reductor ( 4 ) else : reductor = getattr ( x , "__reduce__" , None ) if reductor : rv = reductor () else : raise Error ( "un(deep)copyable object of type %s " % cls )
  • Improved: if reductor := dispatch_table . get ( cls ): rv = reductor ( x ) elif reductor := getattr ( x , "__reduce_ex__" , None ): rv = reductor ( 4 ) elif reductor := getattr ( x , "__reduce__" , None ): rv = reductor () else : raise Error ( "un(deep)copyable object of type %s " % cls )

tz is only used for s += tz , moving its assignment inside the if helps to show its scope.

  • Current: s = _format_time ( self . _hour , self . _minute , self . _second , self . _microsecond , timespec ) tz = self . _tzstr () if tz : s += tz return s
  • Improved: s = _format_time ( self . _hour , self . _minute , self . _second , self . _microsecond , timespec ) if tz := self . _tzstr (): s += tz return s

Calling fp.readline() in the while condition and calling .match() on the if lines make the code more compact without making it harder to understand.

  • Current: while True : line = fp . readline () if not line : break m = define_rx . match ( line ) if m : n , v = m . group ( 1 , 2 ) try : v = int ( v ) except ValueError : pass vars [ n ] = v else : m = undef_rx . match ( line ) if m : vars [ m . group ( 1 )] = 0
  • Improved: while line := fp . readline (): if m := define_rx . match ( line ): n , v = m . group ( 1 , 2 ) try : v = int ( v ) except ValueError : pass vars [ n ] = v elif m := undef_rx . match ( line ): vars [ m . group ( 1 )] = 0

A list comprehension can map and filter efficiently by capturing the condition:

Similarly, a subexpression can be reused within the main expression, by giving it a name on first use:

Note that in both cases the variable y is bound in the containing scope (i.e. at the same level as results or stuff ).

Assignment expressions can be used to good effect in the header of an if or while statement:

Particularly with the while loop, this can remove the need to have an infinite loop, an assignment, and a condition. It also creates a smooth parallel between a loop which simply uses a function call as its condition, and one which uses that as its condition but also uses the actual value.

An example from the low-level UNIX world:

Rejected alternative proposals

Proposals broadly similar to this one have come up frequently on python-ideas. Below are a number of alternative syntaxes, some of them specific to comprehensions, which have been rejected in favour of the one given above.

A previous version of this PEP proposed subtle changes to the scope rules for comprehensions, to make them more usable in class scope and to unify the scope of the “outermost iterable” and the rest of the comprehension. However, this part of the proposal would have caused backwards incompatibilities, and has been withdrawn so the PEP can focus on assignment expressions.

Broadly the same semantics as the current proposal, but spelled differently.

Since EXPR as NAME already has meaning in import , except and with statements (with different semantics), this would create unnecessary confusion or require special-casing (e.g. to forbid assignment within the headers of these statements).

(Note that with EXPR as VAR does not simply assign the value of EXPR to VAR – it calls EXPR.__enter__() and assigns the result of that to VAR .)

Additional reasons to prefer := over this spelling include:

  • In if f(x) as y the assignment target doesn’t jump out at you – it just reads like if f x blah blah and it is too similar visually to if f(x) and y .
  • import foo as bar
  • except Exc as var
  • with ctxmgr() as var

To the contrary, the assignment expression does not belong to the if or while that starts the line, and we intentionally allow assignment expressions in other contexts as well.

  • NAME = EXPR
  • if NAME := EXPR

reinforces the visual recognition of assignment expressions.

This syntax is inspired by languages such as R and Haskell, and some programmable calculators. (Note that a left-facing arrow y <- f(x) is not possible in Python, as it would be interpreted as less-than and unary minus.) This syntax has a slight advantage over ‘as’ in that it does not conflict with with , except and import , but otherwise is equivalent. But it is entirely unrelated to Python’s other use of -> (function return type annotations), and compared to := (which dates back to Algol-58) it has a much weaker tradition.

This has the advantage that leaked usage can be readily detected, removing some forms of syntactic ambiguity. However, this would be the only place in Python where a variable’s scope is encoded into its name, making refactoring harder.

Execution order is inverted (the indented body is performed first, followed by the “header”). This requires a new keyword, unless an existing keyword is repurposed (most likely with: ). See PEP 3150 for prior discussion on this subject (with the proposed keyword being given: ).

This syntax has fewer conflicts than as does (conflicting only with the raise Exc from Exc notation), but is otherwise comparable to it. Instead of paralleling with expr as target: (which can be useful but can also be confusing), this has no parallels, but is evocative.

One of the most popular use-cases is if and while statements. Instead of a more general solution, this proposal enhances the syntax of these two statements to add a means of capturing the compared value:

This works beautifully if and ONLY if the desired condition is based on the truthiness of the captured value. It is thus effective for specific use-cases (regex matches, socket reads that return '' when done), and completely useless in more complicated cases (e.g. where the condition is f(x) < 0 and you want to capture the value of f(x) ). It also has no benefit to list comprehensions.

Advantages: No syntactic ambiguities. Disadvantages: Answers only a fraction of possible use-cases, even in if / while statements.

Another common use-case is comprehensions (list/set/dict, and genexps). As above, proposals have been made for comprehension-specific solutions.

This brings the subexpression to a location in between the ‘for’ loop and the expression. It introduces an additional language keyword, which creates conflicts. Of the three, where reads the most cleanly, but also has the greatest potential for conflict (e.g. SQLAlchemy and numpy have where methods, as does tkinter.dnd.Icon in the standard library).

As above, but reusing the with keyword. Doesn’t read too badly, and needs no additional language keyword. Is restricted to comprehensions, though, and cannot as easily be transformed into “longhand” for-loop syntax. Has the C problem that an equals sign in an expression can now create a name binding, rather than performing a comparison. Would raise the question of why “with NAME = EXPR:” cannot be used as a statement on its own.

As per option 2, but using as rather than an equals sign. Aligns syntactically with other uses of as for name binding, but a simple transformation to for-loop longhand would create drastically different semantics; the meaning of with inside a comprehension would be completely different from the meaning as a stand-alone statement, while retaining identical syntax.

Regardless of the spelling chosen, this introduces a stark difference between comprehensions and the equivalent unrolled long-hand form of the loop. It is no longer possible to unwrap the loop into statement form without reworking any name bindings. The only keyword that can be repurposed to this task is with , thus giving it sneakily different semantics in a comprehension than in a statement; alternatively, a new keyword is needed, with all the costs therein.

There are two logical precedences for the := operator. Either it should bind as loosely as possible, as does statement-assignment; or it should bind more tightly than comparison operators. Placing its precedence between the comparison and arithmetic operators (to be precise: just lower than bitwise OR) allows most uses inside while and if conditions to be spelled without parentheses, as it is most likely that you wish to capture the value of something, then perform a comparison on it:

Once find() returns -1, the loop terminates. If := binds as loosely as = does, this would capture the result of the comparison (generally either True or False ), which is less useful.

While this behaviour would be convenient in many situations, it is also harder to explain than “the := operator behaves just like the assignment statement”, and as such, the precedence for := has been made as close as possible to that of = (with the exception that it binds tighter than comma).

Some critics have claimed that the assignment expressions should allow unparenthesized tuples on the right, so that these two would be equivalent:

(With the current version of the proposal, the latter would be equivalent to ((point := x), y) .)

However, adopting this stance would logically lead to the conclusion that when used in a function call, assignment expressions also bind less tight than comma, so we’d have the following confusing equivalence:

The less confusing option is to make := bind more tightly than comma.

It’s been proposed to just always require parentheses around an assignment expression. This would resolve many ambiguities, and indeed parentheses will frequently be needed to extract the desired subexpression. But in the following cases the extra parentheses feel redundant:

Frequently Raised Objections

C and its derivatives define the = operator as an expression, rather than a statement as is Python’s way. This allows assignments in more contexts, including contexts where comparisons are more common. The syntactic similarity between if (x == y) and if (x = y) belies their drastically different semantics. Thus this proposal uses := to clarify the distinction.

The two forms have different flexibilities. The := operator can be used inside a larger expression; the = statement can be augmented to += and its friends, can be chained, and can assign to attributes and subscripts.

Previous revisions of this proposal involved sublocal scope (restricted to a single statement), preventing name leakage and namespace pollution. While a definite advantage in a number of situations, this increases complexity in many others, and the costs are not justified by the benefits. In the interests of language simplicity, the name bindings created here are exactly equivalent to any other name bindings, including that usage at class or module scope will create externally-visible names. This is no different from for loops or other constructs, and can be solved the same way: del the name once it is no longer needed, or prefix it with an underscore.

(The author wishes to thank Guido van Rossum and Christoph Groth for their suggestions to move the proposal in this direction. [2] )

As expression assignments can sometimes be used equivalently to statement assignments, the question of which should be preferred will arise. For the benefit of style guides such as PEP 8 , two recommendations are suggested.

  • If either assignment statements or assignment expressions can be used, prefer statements; they are a clear declaration of intent.
  • If using assignment expressions would lead to ambiguity about execution order, restructure it to use statements instead.

The authors wish to thank Alyssa Coghlan and Steven D’Aprano for their considerable contributions to this proposal, and members of the core-mentorship mailing list for assistance with implementation.

Appendix A: Tim Peters’s findings

Here’s a brief essay Tim Peters wrote on the topic.

I dislike “busy” lines of code, and also dislike putting conceptually unrelated logic on a single line. So, for example, instead of:

instead. So I suspected I’d find few places I’d want to use assignment expressions. I didn’t even consider them for lines already stretching halfway across the screen. In other cases, “unrelated” ruled:

is a vast improvement over the briefer:

The original two statements are doing entirely different conceptual things, and slamming them together is conceptually insane.

In other cases, combining related logic made it harder to understand, such as rewriting:

as the briefer:

The while test there is too subtle, crucially relying on strict left-to-right evaluation in a non-short-circuiting or method-chaining context. My brain isn’t wired that way.

But cases like that were rare. Name binding is very frequent, and “sparse is better than dense” does not mean “almost empty is better than sparse”. For example, I have many functions that return None or 0 to communicate “I have nothing useful to return in this case, but since that’s expected often I’m not going to annoy you with an exception”. This is essentially the same as regular expression search functions returning None when there is no match. So there was lots of code of the form:

I find that clearer, and certainly a bit less typing and pattern-matching reading, as:

It’s also nice to trade away a small amount of horizontal whitespace to get another _line_ of surrounding code on screen. I didn’t give much weight to this at first, but it was so very frequent it added up, and I soon enough became annoyed that I couldn’t actually run the briefer code. That surprised me!

There are other cases where assignment expressions really shine. Rather than pick another from my code, Kirill Balunov gave a lovely example from the standard library’s copy() function in copy.py :

The ever-increasing indentation is semantically misleading: the logic is conceptually flat, “the first test that succeeds wins”:

Using easy assignment expressions allows the visual structure of the code to emphasize the conceptual flatness of the logic; ever-increasing indentation obscured it.

A smaller example from my code delighted me, both allowing to put inherently related logic in a single line, and allowing to remove an annoying “artificial” indentation level:

That if is about as long as I want my lines to get, but remains easy to follow.

So, in all, in most lines binding a name, I wouldn’t use assignment expressions, but because that construct is so very frequent, that leaves many places I would. In most of the latter, I found a small win that adds up due to how often it occurs, and in the rest I found a moderate to major win. I’d certainly use it more often than ternary if , but significantly less often than augmented assignment.

I have another example that quite impressed me at the time.

Where all variables are positive integers, and a is at least as large as the n’th root of x, this algorithm returns the floor of the n’th root of x (and roughly doubling the number of accurate bits per iteration):

It’s not obvious why that works, but is no more obvious in the “loop and a half” form. It’s hard to prove correctness without building on the right insight (the “arithmetic mean - geometric mean inequality”), and knowing some non-trivial things about how nested floor functions behave. That is, the challenges are in the math, not really in the coding.

If you do know all that, then the assignment-expression form is easily read as “while the current guess is too large, get a smaller guess”, where the “too large?” test and the new guess share an expensive sub-expression.

To my eyes, the original form is harder to understand:

This appendix attempts to clarify (though not specify) the rules when a target occurs in a comprehension or in a generator expression. For a number of illustrative examples we show the original code, containing a comprehension, and the translation, where the comprehension has been replaced by an equivalent generator function plus some scaffolding.

Since [x for ...] is equivalent to list(x for ...) these examples all use list comprehensions without loss of generality. And since these examples are meant to clarify edge cases of the rules, they aren’t trying to look like real code.

Note: comprehensions are already implemented via synthesizing nested generator functions like those in this appendix. The new part is adding appropriate declarations to establish the intended scope of assignment expression targets (the same scope they resolve to as if the assignment were performed in the block containing the outermost comprehension). For type inference purposes, these illustrative expansions do not imply that assignment expression targets are always Optional (but they do indicate the target binding scope).

Let’s start with a reminder of what code is generated for a generator expression without assignment expression.

  • Original code (EXPR usually references VAR): def f (): a = [ EXPR for VAR in ITERABLE ]
  • Translation (let’s not worry about name conflicts): def f (): def genexpr ( iterator ): for VAR in iterator : yield EXPR a = list ( genexpr ( iter ( ITERABLE )))

Let’s add a simple assignment expression.

  • Original code: def f (): a = [ TARGET := EXPR for VAR in ITERABLE ]
  • Translation: def f (): if False : TARGET = None # Dead code to ensure TARGET is a local variable def genexpr ( iterator ): nonlocal TARGET for VAR in iterator : TARGET = EXPR yield TARGET a = list ( genexpr ( iter ( ITERABLE )))

Let’s add a global TARGET declaration in f() .

  • Original code: def f (): global TARGET a = [ TARGET := EXPR for VAR in ITERABLE ]
  • Translation: def f (): global TARGET def genexpr ( iterator ): global TARGET for VAR in iterator : TARGET = EXPR yield TARGET a = list ( genexpr ( iter ( ITERABLE )))

Or instead let’s add a nonlocal TARGET declaration in f() .

  • Original code: def g (): TARGET = ... def f (): nonlocal TARGET a = [ TARGET := EXPR for VAR in ITERABLE ]
  • Translation: def g (): TARGET = ... def f (): nonlocal TARGET def genexpr ( iterator ): nonlocal TARGET for VAR in iterator : TARGET = EXPR yield TARGET a = list ( genexpr ( iter ( ITERABLE )))

Finally, let’s nest two comprehensions.

  • Original code: def f (): a = [[ TARGET := i for i in range ( 3 )] for j in range ( 2 )] # I.e., a = [[0, 1, 2], [0, 1, 2]] print ( TARGET ) # prints 2
  • Translation: def f (): if False : TARGET = None def outer_genexpr ( outer_iterator ): nonlocal TARGET def inner_generator ( inner_iterator ): nonlocal TARGET for i in inner_iterator : TARGET = i yield i for j in outer_iterator : yield list ( inner_generator ( range ( 3 ))) a = list ( outer_genexpr ( range ( 2 ))) print ( TARGET )

Because it has been a point of confusion, note that nothing about Python’s scoping semantics is changed. Function-local scopes continue to be resolved at compile time, and to have indefinite temporal extent at run time (“full closures”). Example:

This document has been placed in the public domain.

Source: https://github.com/python/peps/blob/main/peps/pep-0572.rst

Last modified: 2023-10-11 12:05:51 GMT

  • SyntaxError: cannot assign to expression here. Maybe you meant '==' instead of '='?

avatar

Last updated: Apr 8, 2024 Reading time · 6 min

banner

# Table of Contents

  • SyntaxError: cannot assign to literal here (Python)
Note: If you got the error: "SyntaxError: cannot assign to literal here" , click on the second subheading.

# SyntaxError: cannot assign to expression here. Maybe you meant '==' instead of '='?

The Python "SyntaxError: cannot assign to expression here. Maybe you meant '==' instead of '='?" occurs when we have an expression on the left-hand side of an assignment.

To solve the error, specify the variable name on the left and the expression on the right-hand side.

syntaxerror cannot assign to expression here

Here is an example of how the error occurs.

hyphen in the name of the variable

# Don't use hyphens in variable names

If this is how you got the error, use an underscore instead of a hyphen.

dont use hyphens in variable names

The name of a variable must start with a letter or an underscore.

A variable name can contain alpha-numeric characters ( a-z , A-Z , 0-9 ) and underscores _ .

Variable names cannot contain any other characters than the aforementioned.

# Don't use expressions on the left-hand side of an assignment

Here is another example of how the error occurs.

We have an expression on the left-hand side which is not allowed.

The variable name has to be specified on the left-hand side, and the expression on the right-hand side.

use expression on right hand side

Now that the division is moved to the right-hand side, the error is resolved.

# Use double equals (==) when comparing values

If you mean to compare two values, use the double equals (==) sign.

use double equals when comparing values

Notice that we use double equals == when comparing two values and a single equal = sign for assignment.

Double equals (==) is used for comparison and single equals (=) is used for assignment.

If you use a single equal (=) sign when comparing values, the error is raised.

# Declaring a dictionary

If you get the error when declaring a variable that stores a dictionary, use the following syntax.

Notice that each key and value are separated by a colon and each key-value pair is separated by a comma.

The error is sometimes raised if you have a missing comma between the key-value pairs of a dictionary.

# SyntaxError: cannot assign to literal here (Python)

The Python "SyntaxError: cannot assign to literal here. Maybe you meant '==' instead of '='?" occurs when we try to assign to a literal (e.g. a string or a number).

To solve the error, specify the variable name on the left and the value on the right-hand side of the assignment.

syntaxerror cannot assign to literal here

Here are 2 examples of how the error occurs.

value on left hand side of assignment

Literal values are strings, integers, booleans and floating-point numbers.

# Variable names on the left and values on the right-hand side

When declaring a variable make sure the variable name is on the left-hand side and the value is on the right-hand side of the assignment ( = ).

variable names on left and values on right hand side

Notice that variable names should be wrapped in quotes as that is a string literal.

The string "name" is always going to be equal to the string "name" , and the number 100 is always going to be equal to the number 100 , so we cannot assign a value to a literal.

# A variable is a container that stores a specific value

You can think of a variable as a container that stores a specific value.

Variable names should not be wrapped in quotes.

# Declaring multiple variables on the same line

If you got the error while declaring multiple variables on the same line, use the following syntax.

The variable names are still on the left, and the values are on the right-hand side.

You can also use a semicolon to declare multiple variables on the same line.

However, this is uncommon and unnecessary.

# Performing an equality comparison

If you meant to perform an equality comparison, use double equals.

We use double equals == for comparison and single equals = for assignment.

If you need to check if a value is less than or equal to another, use <= .

Similarly, if you need to check if a value is greater than or equal to another, use >= operator.

Make sure you don't use a single equals = sign to compare values because single equals = is used for assignment and not for comparison.

# Assigning to a literal in a for loop

The error also occurs if you try to assign a value to a literal in a for loop by mistake.

Notice that we wrapped the item variable in quotes which makes it a string literal.

Instead, remove the quotes to declare the variable correctly.

Now we declared an item variable that gets set to the current list item on each iteration.

# Using a dictionary

If you meant to declare a dictionary, use curly braces.

A dictionary is a mapping of key-value pairs.

You can use square brackets if you need to add a key-value pair to a dictionary.

If you need to iterate over a dictionary, use a for loop with dict.items() .

The dict.items method returns a new view of the dictionary's items ((key, value) pairs).

# Valid variable names in Python

Note that variable names cannot start with numbers or be wrapped in quotes.

Variable names in Python are case-sensitive.

The 2 variables in the example are completely different and are stored in different locations in memory.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

  • SyntaxError: cannot assign to function call here in Python

book cover

Borislav Hadzhiev

Web Developer

buy me a coffee

Copyright © 2024 Borislav Hadzhiev

IMAGES

  1. hqdefault.jpg?sqp=-oaymwEWCKgBEF5IWvKriqkDCQgBFQAAiEIYAQ==&rs

    python lambda cannot contain assignment

  2. Python lambda function

    python lambda cannot contain assignment

  3. Python Tutorial

    python lambda cannot contain assignment

  4. Cómo usar funciones Lambda en Python [With Examples] ️kirukiru.es

    python lambda cannot contain assignment

  5. Lambda in python

    python lambda cannot contain assignment

  6. How to Effectively Use Lambda Functions in Python as a Data Scientist

    python lambda cannot contain assignment

VIDEO

  1. Deploy Python Script To AWS Lambda with Trigger

  2. C++ From Scratch: Lambdas

  3. A212 ISMP SENI Tugasan Kelarai. Motif Flora,Fauna dan Abstrak

  4. Lambda in PYTHON?? #python #programming #coding

  5. Python tutorial Session 15: Lambda with Filter/Map/Reduce functions

  6. Lambda Functions in Python

COMMENTS

  1. Why are assignments not allowed in Python's `lambda` expressions?

    The entire reason lambda exists is that it's an expression. 1 If you want something that's like lambda but is a statement, that's just def.. Python expressions cannot contain statements. This is, in fact, fundamental to the language, and Python gets a lot of mileage out of that decision.

  2. Assignment inside lambda expression in Python

    The assignment expression operator := added in Python 3.8 supports assignment inside of lambda expressions. This operator can only appear within a parenthesized (...), bracketed [...], or braced {...} expression for syntactic reasons. For example, we will be able to write the following: import sys. say_hello = lambda: (.

  3. Python workarounds for assignment in lambda

    r=range;r(a)+r(b) print s[1:],s[1:]*2. r=s[1:];print r,r*2. Other languages have workarounds, Octave for example. There are known tricks for Python, but they are long, clunky, and/or limited-use. A short, general-purpose method to simulate assignment in a lambda would revolutionize Python golfing. What are ways for a Python golfer to overcome ...

  4. How to Use Python Lambda Functions

    A Python lambda function behaves like a normal function in regard to arguments. Therefore, a lambda parameter can be initialized with a default value: the parameter n takes the outer n as a default value. The Python lambda function could have been written as lambda x=n: print(x) and have the same result.

  5. Python Lambda Functions

    You can also use lambda functions to return functions as values. For example: def make_adder(x): return lambda y: x + y. add5 = make_adder(5) print(add5(3)) # Output: 8. In this example, the make_adder function takes one input x and returns a lambda function that takes one input y and returns the sum of x and y.

  6. Python lambda function

    Python lambda as Anonymous function. The lambda keyword creates an anonymous function within a Python expression. However, the simple syntax of Python limits the body of lambda functions to be pure expressions. In other words, the body cannot contain other Python statements such as while, try, etc. Assignment with = is also a statement, so it ...

  7. Python Lambda Function: Secret to Anonymous and Concise Code

    We write a lambda function as a single line of execution, which means we cannot include multiple lines of code in it. However, we can include multiple expressions by separating them with commas. Example of invalid Python lambda function syntax: # Invalid syntax. lambda x, y: x += 1. y += 1. return x + y. # Valid syntax.

  8. Why can't Python lambda expressions contain statements?

    Yes, Python Lambda Expressions cannot contain statements. Before deep diving the reason, let us understand what is a Lambda, its expressions, and statements. The Lambda expressions allow defining anonymous functions. A lambda function is an anonymous function i.e. a function without a name. Let us see the syntax −. The keyword lambda defines ...

  9. Issue 232313: error message confusing for assignment in lambda

    I put in a hack to make this produce: SyntaxError: lambda cannot contain assignment This triggers if and only if the LHS test bottoms out at a lambdef. Solves nothing in general, but is a one-liner change that catches this kind of case reliably, and hurts nothing else.

  10. Design and History FAQ

    Starting in Python 3.8, you can! Assignment expressions using the walrus operator := assign a variable in an expression: ... Python lambda expressions cannot contain statements because Python's syntactic framework can't handle statements nested inside expressions. However, in Python, this is not a serious problem. ...

  11. Assignment OR expressions fail on using lambda expressions #95788

    a = b or d or c # a = 10. Then, think of an example of lambda expression that contains or. b = None. a = b or lambda x: 0 or 5. This code can be interpreted in two ways. a = b or (lambda x: 0) or 5 # a = <function <lambda> at 0x~~~> (which takes one argument named x and always returns 0)

  12. Python's Assignment Operator: Write Robust Assignments

    To create a new variable or to update the value of an existing one in Python, you'll use an assignment statement. This statement has the following three components: A left operand, which must be a variable. The assignment operator ( =) A right operand, which can be a concrete value, an object, or an expression.

  13. error message confusing for assignment in lambda #33922

    Python 2.1a1 (#4, Feb 11 2001, 16:05:58) [GCC 2.95.2 20000220 (Debian GNU/Linux)] on linux2 Type "copyright", ... SyntaxError: lambda cannot contain assignment. This triggers if and only if the LHS test bottoms out at a lambdef. Solves nothing in general, but is a one-liner change that catches this kind of case reliably, and hurts nothing else. ...

  14. python

    lambda 存在的全部原因是它是一个表达式。 1 如果您想要类似于 lambda 但只是一个语句的东西,那只是def.. Python 表达式不能包含语句。事实上,这是该语言的基础,Python 从该决定中获得了很多好处。这就是流程控制的缩进有效而不是像许多其他尝试(如 CoffeeScript)那样笨拙的原因。

  15. python

    SyntaxError: lambda cannot contain assignment. python; variables; lambda; Share. Improve this question. Follow ... How to assign values in lambda function in Python? 0. Lambda in a function. Hot Network Questions Early computer art - reproducing Georg Nees "Schotter" and "K27"

  16. How do I make an assignment inside lambda function?

    Nov-13-2016, 05:09 PM. Lambas in Python must be an expression. Assignments are statements. Things like return, break, continue, the equals sign, and that are all statements. While and for loops are also not expressions, although comprehensions are expressions. exec is also a statement, not a function (since functions can be used for expressions ...

  17. PEP 572

    In most cases the scope in which the target will be bound is self-explanatory: it is the current scope. If this scope contains a nonlocal or global declaration for the target, the assignment expression honors that. A lambda (being an explicit, if anonymous, function definition) counts as a scope for this purpose.

  18. SyntaxError: cannot assign to expression here. Maybe you meant

    # SyntaxError: cannot assign to literal here (Python) The Python "SyntaxError: cannot assign to literal here. Maybe you meant '==' instead of '='?" occurs when we try to assign to a literal (e.g. a string or a number). To solve the error, specify the variable name on the left and the value on the right-hand side of the assignment.

  19. python

    1. instead of modifying the Request object (which mypy is helpfully erroring on as generally an assignment to a function is a mistake or a monkeypatch hack) you can set the method directly in construction of Request: request = urllib.request.Request(request_url, serialized_body, headers=header, method='POST') this parameter was added in python3.3.

  20. Python 高阶Lambda函数的四种常见错误-CSDN博客

    Python 高阶Lambda函数的四种常见错误. Lambda 函数是 Python 中的匿名函数。. 当你需要完成一件小工作时,在本地环境中使用它们可以让工作得心应手。. 有些人将它们简称为 lambdas,它们的语法如下:. lambda 关键字可以用来创建一个 lambda 函数,紧跟其后的是参数 ...

  21. Python Dictionary Object: SyntaxError: expression cannot contain

    File "<stdin>", line 1 SyntaxError: expression cannot contain assignment, perhaps you meant "=="? Can someone tell me, why am I allowed to create dictionary with integer keys using Statement 1, but not with Statement 2? ... As per the Python syntax, keyword arguments are of the form identifier '=' expression. An identifier may not start with a ...