Operators and Expressions in Python

Operators and Expressions in Python

Table of Contents

Getting Started With Operators and Expressions

The assignment operator and statements, arithmetic operators and expressions in python, comparison of integer values, comparison of floating-point values, comparison of strings, comparison of lists and tuples, boolean expressions involving boolean operands, evaluation of regular objects in a boolean context, boolean expressions involving other types of operands, compound logical expressions and short-circuit evaluation, idioms that exploit short-circuit evaluation, compound vs chained expressions, conditional expressions or the ternary operator, identity operators and expressions in python, membership operators and expressions in python, concatenation and repetition operators and expressions, the walrus operator and assignment expressions, bitwise operators and expressions in python, operator precedence in python, augmented assignment operators and expressions.

In Python, operators are special symbols, combinations of symbols, or keywords that designate some type of computation. You can combine objects and operators to build expressions that perform the actual computation. So, operators are the building blocks of expressions, which you can use to manipulate your data. Therefore, understanding how operators work in Python is essential for you as a programmer.

In this tutorial, you’ll learn about the operators that Python currently supports. You’ll also learn the basics of how to use these operators to build expressions.

In this tutorial, you’ll:

  • Get to know Python’s arithmetic operators and use them to build arithmetic expressions
  • Explore Python’s comparison , Boolean , identity , and membership operators
  • Build expressions with comparison, Boolean, identity, and membership operators
  • Learn about Python’s bitwise operators and how to use them
  • Combine and repeat sequences using the concatenation and repetition operators
  • Understand the augmented assignment operators and how they work

To get the most out of this tutorial, you should have a basic understanding of Python programming concepts, such as variables , assignments , and built-in data types .

Free Bonus: Click here to download your comprehensive cheat sheet covering the various operators in Python.

Take the Quiz: Test your knowledge with our interactive “Python Operators and Expressions” quiz. You’ll receive a score upon completion to help you track your learning progress:

Interactive Quiz

Test your understanding of Python operators and expressions.

In programming, an operator is usually a symbol or combination of symbols that allows you to perform a specific operation. This operation can act on one or more operands . If the operation involves a single operand, then the operator is unary . If the operator involves two operands, then the operator is binary .

For example, in Python, you can use the minus sign ( - ) as a unary operator to declare a negative number. You can also use it to subtract two numbers:

In this code snippet, the minus sign ( - ) in the first example is a unary operator, and the number 273.15 is the operand. In the second example, the same symbol is a binary operator, and the numbers 5 and 2 are its left and right operands.

Programming languages typically have operators built in as part of their syntax. In many languages, including Python, you can also create your own operator or modify the behavior of existing ones, which is a powerful and advanced feature to have.

In practice, operators provide a quick shortcut for you to manipulate data, perform mathematical calculations, compare values, run Boolean tests, assign values to variables, and more. In Python, an operator may be a symbol, a combination of symbols, or a keyword , depending on the type of operator that you’re dealing with.

For example, you’ve already seen the subtraction operator, which is represented with a single minus sign ( - ). The equality operator is a double equal sign ( == ). So, it’s a combination of symbols:

In this example, you use the Python equality operator ( == ) to compare two numbers. As a result, you get True , which is one of Python’s Boolean values.

Speaking of Boolean values, the Boolean or logical operators in Python are keywords rather than signs, as you’ll learn in the section about Boolean operators and expressions . So, instead of the odd signs like || , && , and ! that many other programming languages use, Python uses or , and , and not .

Using keywords instead of odd signs is a really cool design decision that’s consistent with the fact that Python loves and encourages code’s readability .

You’ll find several categories or groups of operators in Python. Here’s a quick list of those categories:

  • Assignment operators
  • Arithmetic operators
  • Comparison operators
  • Boolean or logical operators
  • Identity operators
  • Membership operators
  • Concatenation and repetition operators
  • Bitwise operators

All these types of operators take care of specific types of computations and data-processing tasks. You’ll learn more about these categories throughout this tutorial. However, before jumping into more practical discussions, you need to know that the most elementary goal of an operator is to be part of an expression . Operators by themselves don’t do much:

As you can see in this code snippet, if you use an operator without the required operands, then you’ll get a syntax error . So, operators must be part of expressions, which you can build using Python objects as operands.

So, what is an expression anyway? Python has simple and compound statements. A simple statement is a construct that occupies a single logical line , like an assignment statement. A compound statement is a construct that occupies multiple logical lines, such as a for loop or a conditional statement. An expression is a simple statement that produces and returns a value.

You’ll find operators in many expressions. Here are a few examples:

In the first two examples, you use the addition and division operators to construct two arithmetic expressions whose operands are integer numbers. In the last example, you use the equality operator to create a comparison expression. In all cases, you get a specific value after executing the expression.

Note that not all expressions use operators. For example, a bare function call is an expression that doesn’t require any operator:

In the first example, you call the built-in abs() function to get the absolute value of -7 . Then, you compute 2 to the power of 8 using the built-in pow() function. These function calls occupy a single logical line and return a value. So, they’re expressions.

Finally, the call to the built-in print() function is another expression. This time, the function doesn’t return a fruitful value, but it still returns None , which is the Python null type . So, the call is technically an expression.

Note: All Python functions have a return value, either explicit or implicit. If you don’t provide an explicit return statement when defining a function, then Python will automatically make the function return None .

Even though all expressions are statements, not all statements are expressions. For example, pure assignment statements don’t return any value, as you’ll learn in a moment. Therefore, they’re not expressions. The assignment operator is a special operator that doesn’t create an expression but a statement.

Note: Since version 3.8, Python also has what it calls assignment expressions. These are special types of assignments that do return a value. You’ll learn more about this topic in the section The Walrus Operator and Assignment Expressions .

Okay! That was a quick introduction to operators and expressions in Python. Now it’s time to dive deeper into the topic. To kick things off, you’ll start with the assignment operator and statements.

The assignment operator is one of the most frequently used operators in Python. The operator consists of a single equal sign ( = ), and it operates on two operands. The left-hand operand is typically a variable , while the right-hand operand is an expression.

Note: As you already learned, the assignment operator doesn’t create an expression. Instead, it creates a statement that doesn’t return any value.

The assignment operator allows you to assign values to variables . Strictly speaking, in Python, this operator makes variables or names refer to specific objects in your computer’s memory. In other words, an assignment creates a reference to a concrete object and attaches that reference to the target variable.

Note: To dive deeper into using the assignment operator, check out Python’s Assignment Operator: Write Robust Assignments .

For example, all the statements below create new variables that hold references to specific objects:

In the first statement, you create the number variable, which holds a reference to the number 42 in your computer’s memory. You can also say that the name number points to 42 , which is a concrete object.

In the rest of the examples, you create other variables that point to other types of objects, such as a string , tuple , and list , respectively.

You’ll use the assignment operator in many of the examples that you’ll write throughout this tutorial. More importantly, you’ll use this operator many times in your own code. It’ll be your forever friend. Now you can dive into other Python operators!

Arithmetic operators are those operators that allow you to perform arithmetic operations on numeric values. Yes, they come from math, and in most cases, you’ll represent them with the usual math signs. The following table lists the arithmetic operators that Python currently supports:

Operator Type Operation Sample Expression Result
Unary Positive without any transformation since this is simply a complement to negation
Binary Addition The arithmetic sum of and
Unary Negation The value of but with the opposite sign
Binary Subtraction subtracted from
Binary Multiplication The product of and
Binary Division The quotient of divided by , expressed as a float
Binary Modulo The remainder of divided by
Binary Floor division or integer division The quotient of divided by , rounded to the next smallest whole number
Binary Exponentiation raised to the power of

Note that a and b in the Sample Expression column represent numeric values, such as integer , floating-point , complex , rational , and decimal numbers.

Here are some examples of these operators in use:

In this code snippet, you first create two new variables, a and b , holding 5 and 2 , respectively. Then you use these variables to create different arithmetic expressions using a specific operator in each expression.

Note: The Python REPL will display the return value of an expression as a way to provide immediate feedback to you. So, when you’re in an interactive session, you don’t need to use the print() function to check the result of an expression. You can just type in the expression and press Enter to get the result.

Again, the standard division operator ( / ) always returns a floating-point number, even if the dividend is evenly divisible by the divisor:

In the first example, 10 is evenly divisible by 5 . Therefore, this operation could return the integer 2 . However, it returns the floating-point number 2.0 . In the second example, 10.0 is a floating-point number, and 5 is an integer. In this case, Python internally promotes 5 to 5.0 and runs the division. The result is a floating-point number too.

Note: With complex numbers, the division operator doesn’t return a floating-point number but a complex one:

Here, you run a division between an integer and a complex number. In this case, the standard division operator returns a complex number.

Finally, consider the following examples of using the floor division ( // ) operator:

Floor division always rounds down . This means that the result is the greatest integer that’s smaller than or equal to the quotient. For positive numbers, it’s as though the fractional portion is truncated, leaving only the integer portion.

Comparison Operators and Expressions in Python

The Python comparison operators allow you to compare numerical values and any other objects that support them. The table below lists all the currently available comparison operators in Python:

Operator Operation Sample Expression Result
Equal to • if the value of is equal to the value of
• otherwise
Not equal to • if isn’t equal to
• otherwise
Less than • if is less than
• otherwise
Less than or equal to • if is less than or equal to
• otherwise
Greater than • if is greater than
• otherwise
Greater than or equal to • if is greater than or equal to
• otherwise

The comparison operators are all binary. This means that they require left and right operands. These operators always return a Boolean value ( True or False ) that depends on the truth value of the comparison at hand.

Note that comparisons between objects of different data types often don’t make sense and sometimes aren’t allowed in Python. For example, you can compare a number and a string for equality with the == operator. However, you’ll get False as a result:

The integer 2 isn’t equal to the string "2" . Therefore, you get False as a result. You can also use the != operator in the above expression, in which case you’ll get True as a result.

Non-equality comparisons between operands of different data types raise a TypeError exception:

In this example, Python raises a TypeError exception because a less than comparison ( < ) doesn’t make sense between an integer and a string. So, the operation isn’t allowed.

It’s important to note that in the context of comparisons, integer and floating-point values are compatible, and you can compare them.

You’ll typically use and find comparison operators in Boolean contexts like conditional statements and while loops . They allow you to make decisions and define a program’s control flow .

The comparison operators work on several types of operands, such as numbers, strings, tuples, and lists. In the following sections, you’ll explore the differences.

Probably, the more straightforward comparisons in Python and in math are those involving integer numbers. They allow you to count real objects, which is a familiar day-to-day task. In fact, the non-negative integers are also called natural numbers . So, comparing this type of number is probably pretty intuitive, and doing so in Python is no exception.

Consider the following examples that compare integer numbers:

In the first set of examples, you define two variables, a and b , to run a few comparisons between them. The value of a is less than the value of b . So, every comparison expression returns the expected Boolean value. The second set of examples uses two values that are equal, and again, you get the expected results.

Comparing floating-point numbers is a bit more complicated than comparing integers. The value stored in a float object may not be precisely what you’d think it would be. For that reason, it’s bad practice to compare floating-point values for exact equality using the == operator.

Consider the example below:

Yikes! The internal representation of this addition isn’t exactly equal to 3.3 , as you can see in the final example. So, comparing x to 3.3 with the equality operator returns False .

To compare floating-point numbers for equality, you need to use a different approach. The preferred way to determine whether two floating-point values are equal is to determine whether they’re close to one another, given some tolerance.

The math module from the standard library provides a function conveniently called isclose() that will help you with float comparison. The function takes two numbers and tests them for approximate equality:

In this example, you use the isclose() function to compare x and 3.3 for approximate equality. This time, you get True as a result because both numbers are close enough to be considered equal.

For further details on using isclose() , check out the Find the Closeness of Numbers With Python isclose() section in The Python math Module: Everything You Need to Know .

You can also use the comparison operators to compare Python strings in your code. In this context, you need to be aware of how Python internally compares string objects. In practice, Python compares strings character by character using each character’s Unicode code point . Unicode is Python’s default character set .

You can use the built-in ord() function to learn the Unicode code point of any character in Python. Consider the following examples:

The uppercase "A" has a lower Unicode point than the lowercase "a" . So, "A" is less than "a" . In the end, Python compares characters using integer numbers. So, the same rules that Python uses to compare integers apply to string comparison.

When it comes to strings with several characters, Python runs the comparison character by character in a loop.

The comparison uses lexicographical ordering , which means that Python compares the first item from each string. If their Unicode code points are different, this difference determines the comparison result. If the Unicode code points are equal, then Python compares the next two characters, and so on, until either string is exhausted:

In this example, Python compares both operands character by character. When it reaches the end of the string, it compares "o" and "O" . Because the lowercase letter has a greater Unicode code point, the first version of the string is greater than the second.

You can also compare strings of different lengths:

In this example, Python runs a character-by-character comparison as usual. If it runs out of characters, then the shorter string is less than the longer one. This also means that the empty string is the smallest possible string.

In your Python journey, you can also face the need to compare lists with other lists and tuples with other tuples. These data types also support the standard comparison operators. Like with strings, when you use a comparison operator to compare two lists or two tuples, Python runs an item-by-item comparison.

Note that Python applies specific rules depending on the type of the contained items. Here are some examples that compare lists and tuples of integer values:

In these examples, you compare lists and tuples of numbers using the standard comparison operators. When comparing these data types, Python runs an item-by-item comparison.

For example, in the first expression above, Python compares the 2 in the left operand and the 2 in the right operand. Because they’re equal, Python continues comparing 3 and 3 to conclude that both lists are equal. The same thing happens in the second example, where you compare tuples containing the same data.

It’s important to note that you can actually compare lists to tuples using the == and != operators. However, you can’t compare lists and tuples using the < , > , <= , and >= operators:

Python supports equality comparison between lists and tuples. However, it doesn’t support the rest of the comparison operators, as you can conclude from the final two examples. If you try to use them, then you get a TypeError telling you that the operation isn’t supported.

You can also compare lists and tuples of different lengths:

In the first two examples, you get True as a result because 5 is less than 8 . That fact is sufficient for Python to solve the comparison. In the second pair of examples, you get False . This result makes sense because the compared sequences don’t have the same length, so they can’t be equal.

In the final pair of examples, Python compares 5 with 5 . They’re equal, so the comparison continues. Because there are no more values to compare in the right-hand operands, Python concludes that the left-hand operands are greater.

As you can see, comparing lists and tuples can be tricky. It’s also an expensive operation that, in the worst case, requires traversing two entire sequences. Things get more complex and expensive when the contained items are also sequences. In those situations, Python will also have to compare items in a value-by-value manner, which adds cost to the operation.

Boolean Operators and Expressions in Python

Python has three Boolean or logical operators: and , or , and not . They define a set of operations denoted by the generic operators AND , OR , and NOT . With these operators, you can create compound conditions.

In the following sections, you’ll learn how the Python Boolean operators work. Especially, you’ll learn that some of them behave differently when you use them with Boolean values or with regular objects as operands.

You’ll find many objects and expressions that are of Boolean type or bool , as Python calls this type. In other words, many objects evaluate to True or False , which are the Python Boolean values.

For example, when you evaluate an expression using a comparison operator, the result of that expression is always of bool type:

In this example, the expression age > 18 returns a Boolean value, which you store in the is_adult variable. Now is_adult is of bool type, as you can see after calling the built-in type() function.

You can also find Python built-in and custom functions that return a Boolean value. This type of function is known as a predicate function. The built-in all() , any() , callable() , and isinstance() functions are all good examples of this practice.

Consider the following examples:

In this code snippet, you first define a variable called number using your old friend the assignment operator. Then you create another variable called validation_conditions . This variable holds a tuple of expressions. The first expression uses isinstance() to check whether number is an integer value.

The second is a compound expression that combines the modulo ( % ) and equality ( == ) operators to create a condition that checks whether the input value is an even number. In this condition, the modulo operator returns the remainder of dividing number by 2 , and the equality operator compares the result with 0 , returning True or False as the comparison’s result.

Then you use the all() function to determine if all the conditions are true. In this example, because number = 42 , the conditions are true, and all() returns True . You can play with the value of number if you’d like to experiment a bit.

In the final two examples, you use the callable() function. As its name suggests, this function allows you to determine whether an object is callable . Being callable means that you can call the object with a pair of parentheses and appropriate arguments, as you’d call any Python function.

The number variable isn’t callable, and the function returns False , accordingly. In contrast, the print() function is callable, so callable() returns True .

All the previous discussion is the basis for understanding how the Python logical operators work with Boolean operands.

Logical expressions involving and , or , and not are straightforward when the operands are Boolean. Here’s a summary. Note that x and y represent Boolean operands:

Operator Sample Expression Result
• if both and are
• otherwise
• if either or is
• otherwise
• if is
• if is

This table summarizes the truth value of expressions that you can create using the logical operators with Boolean operands. There’s something to note in this summary. Unlike and and or , which are binary operators, the not operator is unary, meaning that it operates on one operand. This operand must always be on the right side.

Now it’s time to take a look at how the operators work in practice. Here are a few examples of using the and operator with Boolean operands:

In the first example, both operands return True . Therefore, the and expression returns True as a result. In the second example, the left-hand operand is True , but the right-hand operand is False . Because of this, the and operator returns False .

In the third example, the left-hand operand is False . In this case, the and operator immediately returns False and never evaluates the 3 == 3 condition. This behavior is called short-circuit evaluation . You’ll learn more about it in a moment.

Note: Short-circuit evaluation is also called McCarthy evaluation in honor of computer scientist John McCarthy .

In the final example, both conditions return False . Again, and returns False as a result. However, because of the short-circuit evaluation, the right-hand expression isn’t evaluated.

What about the or operator? Here are a few examples that demonstrate how it works:

In the first three examples, at least one of the conditions returns True . In all cases, the or operator returns True . Note that if the left-hand operand is True , then or applies short-circuit evaluation and doesn’t evaluate the right-hand operand. This makes sense. If the left-hand operand is True , then or already knows the final result. Why would it need to continue the evaluation if the result won’t change?

In the final example, both operands are False , and this is the only situation where or returns False . It’s important to note that if the left-hand operand is False , then or has to evaluate the right-hand operand to arrive at a final conclusion.

Finally, you have the not operator, which negates the current truth value of an object or expression:

If you place not before an expression, then you get the inverse truth value. When the expression returns True , you get False . When the expression evaluates to False , you get True .

There is a fundamental behavior distinction between not and the other two Boolean operators. In a not expression, you always get a Boolean value as a result. That’s not always the rule that governs and and or expressions, as you’ll learn in the Boolean Expressions Involving Other Types of Operands section.

In practice, most Python objects and expressions aren’t Boolean. In other words, most objects and expressions don’t have a True or False value but a different type of value. However, you can use any Python object in a Boolean context, such as a conditional statement or a while loop.

In Python, all objects have a specific truth value. So, you can use the logical operators with all types of operands.

Python has well-established rules to determine the truth value of an object when you use that object in a Boolean context or as an operand in an expression built with logical operators. Here’s what the documentation says about this topic:

By default, an object is considered true unless its class defines either a __bool__() method that returns False or a __len__() method that returns zero, when called with the object. Here are most of the built-in objects considered false: constants defined to be false: None and False . zero of any numeric type: 0 , 0.0 , 0j , Decimal(0) , Fraction(0, 1) empty sequences and collections: '' , () , [] , {} , set() , range(0) ( Source )

You can determine the truth value of an object by calling the built-in bool() function with that object as an argument. If bool() returns True , then the object is truthy . If bool() returns False , then it’s falsy .

For numeric values, you have that a zero value is falsy, while a non-zero value is truthy:

Python considers the zero value of all numeric types falsy. All the other values are truthy, regardless of how close to zero they are.

Note: Instead of a function, bool() is a class. However, because Python developers typically use this class as a function, you’ll find that most people refer to it as a function rather than as a class. Additionally, the documentation lists this class on the built-in functions page. This is one of those cases where practicality beats purity .

When it comes to evaluating strings, you have that an empty string is always falsy, while a non-empty string is truthy:

Note that strings containing white spaces are also truthy in Python’s eyes. So, don’t confuse empty strings with whitespace strings.

Finally, built-in container data types, such as lists, tuples, sets , and dictionaries , are falsy when they’re empty. Otherwise, Python considers them truthy objects:

To determine the truth value of container data types, Python relies on the .__len__() special method . This method provides support for the built-in len() function, which you can use to determine the number of items in a given container.

In general, if .__len__() returns 0 , then Python considers the container a falsy object, which is consistent with the general rules you’ve just learned before.

All the discussion about the truth value of Python objects in this section is key to understanding how the logical operators behave when they take arbitrary objects as operands.

You can also use any objects, such as numbers or strings, as operands to and , or , and not . You can even use combinations of a Boolean object and a regular one. In these situations, the result depends on the truth value of the operands.

Note: Boolean expressions that combine two Boolean operands are a special case of a more general rule that allows you to use the logical operators with all kinds of operands. In every case, you’ll get one of the operands as a result.

You’ve already learned how Python determines the truth value of objects. So, you’re ready to dive into creating expressions with logic operators and regular objects.

To start off, below is a table that summarizes what you get when you use two objects, x and y , in an and expression:

If is returns
Truthy
Falsy

It’s important to emphasize a subtle detail in the above table. When you use and in an expression, you don’t always get True or False as a result. Instead, you get one of the operands. You only get True or False if the returned operand has either of these values.

Here are some code examples that use integer values. Remember that in Python, the zero value of numeric types is falsy. The rest of the values are truthy:

In the first expression, the left-hand operand ( 3 ) is truthy. So, you get the right-hand operand ( 4 ) as a result.

In the second example, the left-hand operand ( 0 ) is falsy, and you get it as a result. In this case, Python applies the short-circuit evaluation technique. It already knows that the whole expression is false because 0 is falsy, so Python returns 0 immediately without evaluating the right-hand operand.

In the final expression, the left-hand operand ( 3 ) is truthy. Therefore Python needs to evaluate the right-hand operand to make a conclusion. As a result, you get the right-hand operand, no matter what its truth value is.

Note: To dive deeper into the and operator, check out Using the “and” Boolean Operator in Python .

When it comes to using the or operator, you also get one of the operands as a result. This is what happens for two arbitrary objects, x and y :

Again, the expression x or y doesn’t evaluate to either True or False . Instead, it returns one of its operands, x or y .

As you can conclude from the above table, if the left-hand operand is truthy, then you get it as a result. Otherwise, you get the second operand. Here are some examples that demonstrate this behavior:

In the first example, the left-hand operand is truthy, and or immediately returns it. In this case, Python doesn’t evaluate the second operand because it already knows the final result. In the second example, the left-hand operand is falsy, and Python has to evaluate the right-hand one to determine the result.

In the last example, the left-hand operand is truthy, and that fact defines the result of the expression. There’s no need to evaluate the right-hand operand.

An expression like x or y is truthy if either x or y is truthy, and falsy if both x and y are falsy. This type of expression returns the first truthy operand that it finds. If both operands are falsy, then the expression returns the right-hand operand. To see this latter behavior in action, consider the following example:

In this specific expression, both operands are falsy. So, the or operator returns the right-hand operand, and the whole expression is falsy as a result.

Note: To learn more about the or operator, check out Using the “or” Boolean Operator in Python .

Finally, you have the not operator. You can also use this one with any object as an operand. Here’s what happens:

The not operator has a uniform behavior. It always returns a Boolean value. This behavior differs from its sibling operators, and and or .

Here are some code examples:

In the first example, the operand, 3 , is truthy from Python’s point of view. So, the operator returns False . In the second example, the operand is falsy, and not returns True .

Note: To better understand the not operator, check out Using the “not” Boolean Operator in Python .

In summary, the Python not operator negates the truth value of an object and always returns a Boolean value. This latter behavior differs from the behavior of its sibling operators and and or , which return operands rather than Boolean values.

So far, you’ve seen expressions with only a single or or and operator and two operands. However, you can also create compound logical expressions with multiple logical operators and operands.

To illustrate how to create a compound expression using or , consider the following toy example:

This expression returns the first truthy value. If all the preceding x variables are falsy, then the expression returns the last value, xn .

Note: In an expression like the one above, Python uses short-circuit evaluation . The operands are evaluated in order from left to right. As soon as one is found to be true, the entire expression is known to be true. At that point, Python stops evaluating operands. The value of the entire expression is that of the x that terminates the evaluation.

To help demonstrate short-circuit evaluation, suppose that you have an identity function , f() , that behaves as follows:

  • Takes a single argument
  • Displays the function and its argument on the screen
  • Returns the argument as its return value

Here’s the code to define this function and also a few examples of how it works:

The f() function displays its argument, which visually confirms whether you called the function. It also returns the argument as you passed it in the call. Because of this behavior, you can make the expression f(arg) be truthy or falsy by specifying a value for arg that’s truthy or falsy, respectively.

Now, consider the following compound logical expression:

In this example, Python first evaluates f(0) , which returns 0 . This value is falsy. The expression isn’t true yet, so the evaluation continues from left to right. The next operand, f(False) , returns False . That value is also falsy, so the evaluation continues.

Next up is f(1) . That evaluates to 1 , which is truthy. At that point, Python stops the evaluation because it already knows that the entire expression is truthy. Consequently, Python returns 1 as the value of the expression and never evaluates the remaining operands, f(2) and f(3) . You can confirm from the output that the f(2) and f(3) calls don’t occur.

A similar behavior appears in an expression with multiple and operators like the following one:

This expression is truthy if all the operands are truthy. If at least one operand is falsy, then the expression is also falsy.

In this example, short-circuit evaluation dictates that Python stops evaluating as soon as an operand happens to be falsy. At that point, the entire expression is known to be false. Once that’s the case, Python stops evaluating operands and returns the falsy operand that terminated the evaluation.

Here are two examples that confirm the short-circuiting behavior:

In both examples, the evaluation stops at the first falsy term— f(False) in the first case, f(0.0) in the second case—and neither the f(2) nor the f(3) call occurs. In the end, the expressions return False and 0.0 , respectively.

If all the operands are truthy, then Python evaluates them all and returns the last (rightmost) one as the value of the expression:

In the first example, all the operands are truthy. The expression is also truthy and returns the last operand. In the second example, all the operands are truthy except for the last one. The expression is falsy and returns the last operand.

As you dig into Python, you’ll find that there are some common idiomatic patterns that exploit short-circuit evaluation for conciseness of expression, performance, and safety. For example, you can take advantage of this type of evaluation for:

  • Avoiding an exception
  • Providing a default value
  • Skipping a costly operation

To illustrate the first point, suppose you have two variables, a and b , and you want to know whether the division of b by a results in a number greater than 0 . In this case, you can run the following expression or condition:

This code works. However, you need to account for the possibility that a might be 0 , in which case you’ll get an exception :

In this example, the divisor is 0 , which makes Python raise a ZeroDivisionError exception. This exception breaks your code. You can skip this error with an expression like the following:

When a is 0 , a != 0 is false. Python’s short-circuit evaluation ensures that the evaluation stops at that point, which means that (b / a) never runs, and the error never occurs.

Using this technique, you can implement a function to determine whether an integer is divisible by another integer:

In this function, if b is 0 , then a / b isn’t defined. So, the numbers aren’t divisible. If b is different from 0 , then the result will depend on the remainder of the division.

Selecting a default value when a specified value is falsy is another idiom that takes advantage of the short-circuit evaluation feature of Python’s logical operators.

For example, say that you have a variable that’s supposed to contain a country’s name. At some point, this variable can end up holding an empty string. If that’s the case, then you’d like the variable to hold a default county name. You can also do this with the or operator:

If country is non-empty, then it’s truthy. In this scenario, the expression will return the first truthy value, which is country in the first or expression. The evaluation stops, and you get "Canada" as a result.

On the other hand, if country is an empty string , then it’s falsy. The evaluation continues to the next operand, default_country , which is truthy. Finally, you get the default country as a result.

Another interesting use case for short-circuit evaluation is to avoid costly operations while creating compound logical expressions. For example, if you have a costly operation that should only run if a given condition is false, then you can use or like in the following snippet:

In this construct, your clean_data() function represents a costly operation. Because of short-circuit evaluation, this function will only run when data_is_clean is false, which means that your data isn’t clean.

Another variation of this technique is when you want to run a costly operation if a given condition is true. In this case, you can use the and operator:

In this example, the and operator evaluates data_is_updated . If this variable is true, then the evaluation continues, and the process_data() function runs. Otherwise, the evaluation stops, and process_data() never runs.

Sometimes you have a compound expression that uses the and operator to join comparison expressions. For example, say that you want to determine if a number is in a given interval. You can solve this problem with a compound expression like the following:

In this example, you use the and operator to join two comparison expressions that allow you to find out if number is in the interval from 0 to 10 , both included.

In Python, you can make this compound expression more concise by chaining the comparison operators together. For example, the following chained expression is equivalent to the previous compound one:

This expression is more concise and readable than the original expression. You can quickly realize that this code is checking if the number is between 0 and 10 . Note that in most programming languages, this chained expression doesn’t make sense. In Python, it works like a charm.

In other programming languages, this expression would probably start by evaluating 0 <= number , which is true. This true value would then be compared with 10 , which doesn’t make much sense, so the expression fails.

Python internally processes this type of expression as an equivalent and expression, such as 0 <= number and number <= 10 . That’s why you get the correct result in the example above.

Python has what it calls conditional expressions . These kinds of expressions are inspired by the ternary operator that looks like a ? b : c and is used in other programming languages. This construct evaluates to b if the value of a is true, and otherwise evaluates to c . Because of this, sometimes the equivalent Python syntax is also known as the ternary operator.

However, in Python, the expression looks more readable:

This expression returns expression_1 if the condition is true and expression_2 otherwise. Note that this expression is equivalent to a regular conditional like the following:

So, why does Python need this syntax? PEP 308 introduced conditional expressions as an effort to avoid the prevalence of error-prone attempts to achieve the same effect of a traditional ternary operator using the and and or operators in an expression like the following:

However, this expression doesn’t work as expected, returning expression_2 when expression_1 is falsy.

Some Python developers would avoid the syntax of conditional expressions in favor of a regular conditional statement. In any case, this syntax can be handy in some situations because it provides a concise tool for writing two-way conditionals.

Here’s an example of how to use the conditional expression syntax in your code:

When day is equal to "Sunday" , the condition is true and you get the first expression, "11AM" , as a result. If the condition is false, then you get the second expression, "9AM" . Note that similarly to the and and or operators, the conditional expression returns the value of one of its expressions rather than a Boolean value.

Python provides two operators, is and is not , that allow you to determine whether two operands have the same identity . In other words, they let you check if the operands refer to the same object. Note that identity isn’t the same thing as equality. The latter aims to check whether two operands contain the same data.

Note: To learn more about the difference between identity and equality, check out Python ‘!=’ Is Not ‘is not’: Comparing Objects in Python .

Here’s a summary of Python’s identity operators. Note that x and y are variables that point to objects:

Operator Sample Expression Result
• if and hold a reference to the same in-memory object
• otherwise
• if points to an object different from the object that points to
• otherwise

These two Python operators are keywords instead of odd symbols. This is part of Python’s goal of favoring readability in its syntax.

Here’s an example of two variables, x and y , that refer to objects that are equal but not identical:

In this example, x and y refer to objects whose value is 1001 . So, they’re equal. However, they don’t reference the same object. That’s why the is operator returns False . You can check an object’s identity using the built-in id() function:

As you can conclude from the id() output, x and y don’t have the same identity. So, they’re different objects, and because of that, the expression x is y returns False . In other words, you get False because you have two different instances of 1001 stored in your computer’s memory.

When you make an assignment like y = x , Python creates a second reference to the same object. Again, you can confirm that with the id() function or the is operator:

In this example, a and b hold references to the same object, the string "Hello, Pythonista!" . Therefore, the id() function returns the same identity when you call it with a and b . Similarly, the is operator returns True .

Note: You should note that, on your computer, you’ll get a different identity number when you call id() in the example above. The key detail is that the identity number will be the same for a and b .

Finally, the is not operator is the opposite of is . So, you can use is not to determine if two names don’t refer to the same object:

In the first example, because x and y point to different objects in your computer’s memory, the is not operator returns True . In the second example, because a and b are references to the same object, the is not operator returns False .

Note: The syntax not x is y also works the same as x is not y . However, the former syntax looks odd and is difficult to read. That’s why Python recognizes is not as an operator and encourages its use for readability.

Again, the is not operator highlights Python’s readability goals. In general, both identity operators allow you to write checks that read as plain English.

Sometimes you need to determine whether a value is present in a container data type, such as a list, tuple, or set. In other words, you may need to check if a given value is or is not a member of a collection of values. Python calls this kind of check a membership test .

Note: For a deep dive into how Python’s membership tests work, check out Python’s “in” and “not in” Operators: Check for Membership .

Membership tests are quite common and useful in programming. As with many other common operations, Python has dedicated operators for membership tests. The table below lists the membership operators in Python:

Operator Sample Expression Result
• if present in
• otherwise
• if present in of values
• otherwise

As usual, Python favors readability by using English words as operators instead of potentially confusing symbols or combinations of symbols.

Note: The syntax not value in collection also works in Python. However, this syntax looks odd and is difficult to read. So, to keep your code clean and readable, you should use value not in collection , which almost reads as plain English.

The Python in and not in operators are binary. This means that you can create membership expressions by connecting two operands with either operator. However, the operands in a membership expression have particular characteristics:

  • Left operand : The value that you want to look for in a collection of values
  • Right operand : The collection of values where the target value may be found

To better understand the in operator, below you have two demonstrative examples consisting of determining whether a value is in a list:

The first expression returns True because 5 is in the list of numbers. The second expression returns False because 8 isn’t in the list.

The not in membership operator runs the opposite test as the in operator. It allows you to check whether an integer value is not in a collection of values:

In the first example, you get False because 5 is in the target list. In the second example, you get True because 8 isn’t in the list of values. This may sound like a tongue twister because of the negative logic. To avoid confusion, remember that you’re trying to determine if the value is not part of a given collection of values.

There are two operators in Python that acquire a slightly different meaning when you use them with sequence data types, such as lists, tuples, and strings. With these types of operands, the + operator defines a concatenation operator , and the * operator represents the repetition operator :

Operator Operation Sample Expression Result
Concatenation A new sequence containing all the items from both operands
Repetition A new sequence containing the items of repeated times

Both operators are binary. The concatenation operator takes two sequences as operands and returns a new sequence of the same type. The repetition operator takes a sequence and an integer number as operands. Like in regular multiplication, the order of the operands doesn’t alter the repetition’s result.

Note: To learn more about concatenating string objects, check out Efficient String Concatenation in Python .

Here are some examples of how the concatenation operator works in practice:

In the first example, you use the concatenation operator ( + ) to join two strings together. The operator returns a completely new string object that combines the two original strings.

In the second example, you concatenate two tuples of letters together. Again, the operator returns a new tuple object containing all the items from the original operands. In the final example, you do something similar but this time with two lists.

Note: To learn more about concatenating lists, check out the Concatenating Lists section in the tutorial Python’s list Data Type: A Deep Dive With Examples .

When it comes to the repetition operator, the idea is to repeat the content of a given sequence a certain number of times. Here are a few examples:

In the first example, you use the repetition operator ( * ) to repeat the "Hello" string three times. In the second example, you change the order of the operands by placing the integer number on the left and the target string on the right. This example shows that the order of the operands doesn’t affect the result.

The next examples use the repetition operators with a tuple and a list, respectively. In both cases, you get a new object of the same type containing the items in the original sequence repeated three times.

Regular assignment statements with the = operator don’t have a return value, as you already learned. Instead, the assignment operator creates or updates variables. Because of this, the operator can’t be part of an expression.

Since Python 3.8 , you have access to a new operator that allows for a new type of assignment. This new assignment is called assignment expression or named expression . The new operator is called the walrus operator , and it’s the combination of a colon and an equal sign ( := ).

Note: The name walrus comes from the fact that this operator resembles the eyes and tusks of a walrus lying on its side. For a deep dive into how this operator works, check out The Walrus Operator: Python’s Assignment Expressions .

Unlike regular assignments, assignment expressions do have a return value, which is why they’re expressions . So, the operator accomplishes two tasks:

  • Returns the expression’s result
  • Assigns the result to a variable

The walrus operator is also a binary operator. Its left-hand operand must be a variable name, and its right-hand operand can be any Python expression. The operator will evaluate the expression, assign its value to the target variable, and return the value.

The general syntax of an assignment expression is as follows:

This expression looks like a regular assignment. However, instead of using the assignment operator ( = ), it uses the walrus operator ( := ). For the expression to work correctly, the enclosing parentheses are required in most use cases. However, in certain situations, you won’t need them. Either way, they won’t hurt you, so it’s safe to use them.

Assignment expressions come in handy when you want to reuse the result of an expression or part of an expression without using a dedicated assignment to grab this value beforehand. It’s particularly useful in the context of a conditional statement. To illustrate, the example below shows a toy function that checks the length of a string object:

In this example, you use a conditional statement to check whether the input string has fewer than 8 characters.

The assignment expression, (n := len(string)) , computes the string length and assigns it to n . Then it returns the value that results from calling len() , which finally gets compared with 8 . This way, you guarantee that you have a reference to the string length to use in further operations.

Bitwise operators treat operands as sequences of binary digits and operate on them bit by bit. Currently, Python supports the following bitwise operators:

Operator Operation Sample Expression Result
Bitwise AND • Each bit position in the result is the logical AND of the bits in the corresponding position of the operands.
• if both bits are , otherwise .
Bitwise OR • Each bit position in the result is the logical of the bits in the corresponding position of the operands.
• if either bit is , otherwise .
Bitwise NOT • Each bit position in the result is the logical negation of the bit in the corresponding position of the operand.
• if the bit is and if the bit is .
Bitwise XOR (exclusive OR) • Each bit position in the result is the logical of the bits in the corresponding position of the operands.
• if the bits in the operands are different, if they’re equal.
Bitwise right shift Each bit is shifted right places.
Bitwise left shift Each bit is shifted left places.

As you can see in this table, most bitwise operators are binary, which means that they expect two operands. The bitwise NOT operator ( ~ ) is the only unary operator because it expects a single operand, which should always appear at the right side of the expression.

You can use Python’s bitwise operators to manipulate your data at its most granular level, the bits. These operators are commonly useful when you want to write low-level algorithms, such as compression, encryption, and others.

Note: For a deep dive into the bitwise operators, check out Bitwise Operators in Python . You can also check out Build a Maze Solver in Python Using Graphs for an example of using bitwise operators to construct a binary file format.

Here are some examples that illustrate how some of the bitwise operators work in practice:

In the first example, you use the bitwise AND operator. The commented lines begin with # and provide a visual representation of what happens at the bit level. Note how each bit in the result is the logical AND of the bits in the corresponding position of the operands.

The second example shows how the bitwise OR operator works. In this case, the resulting bits are the logical OR test of the corresponding bits in the operands.

In all the examples, you’ve used the built-in bin() function to display the result as a binary object. If you don’t wrap the expression in a call to bin() , then you’ll get the integer representation of the output.

Up to this point, you’ve coded sample expressions that mostly use one or two different types of operators. However, what if you need to create compound expressions that use several different types of operators, such as comparison, arithmetic, Boolean, and others? How does Python decide which operation runs first?

Consider the following math expression:

There might be ambiguity in this expression. Should Python perform the addition 20 + 4 first and then multiply the result by 10 ? Should Python run the multiplication 4 * 10 first, and the addition second?

Because the result is 60 , you can conclude that Python has chosen the latter approach. If it had chosen the former, then the result would be 240 . This follows a standard algebraic rule that you’ll find in virtually all programming languages.

All operators that Python supports have a precedence compared to other operators. This precedence defines the order in which Python runs the operators in a compound expression.

In an expression, Python runs the operators of highest precedence first. After obtaining those results, Python runs the operators of the next highest precedence. This process continues until the expression is fully evaluated. Any operators of equal precedence are performed in left-to-right order.

Here’s the order of precedence of the Python operators that you’ve seen so far, from highest to lowest:

Operators Description
Exponentiation
, , Unary positive, unary negation, bitwise negation
, , , Multiplication, division, floor division,
, Addition, subtraction
, Bitwise shifts
Bitwise AND
Bitwise XOR
Bitwise OR
, , , , , , , , , Comparisons, identity, and membership
Boolean NOT
Boolean AND
Boolean OR
Walrus

Operators at the top of the table have the highest precedence, and those at the bottom of the table have the lowest precedence. Any operators in the same row of the table have equal precedence.

Getting back to your initial example, Python runs the multiplication because the multiplication operator has a higher precedence than the addition one.

Here’s another illustrative example:

In the example above, Python first raises 3 to the power of 4 , which equals 81 . Then, it carries out the multiplications in order from left to right: 2 * 81 = 162 and 162 * 5 = 810 .

You can override the default operator precedence using parentheses to group terms as you do in math. The subexpressions in parentheses will run before expressions that aren’t in parentheses.

Here are some examples that show how a pair of parentheses can affect the result of an expression:

In the first example, Python computes the expression 20 + 4 first because it’s wrapped in parentheses. Then Python multiplies the result by 10 , and the expression returns 240 . This result is completely different from what you got at the beginning of this section.

In the second example, Python evaluates 4 * 5 first. Then it raises 3 to the power of the resulting value. Finally, Python multiplies the result by 2 , returning 6973568802 .

There’s nothing wrong with making liberal use of parentheses, even when they aren’t necessary to change the order of evaluation. Sometimes it’s a good practice to use parentheses because they can improve your code’s readability and relieve the reader from having to recall operator precedence from memory.

Consider the following example:

Here the parentheses are unnecessary, as the comparison operators have higher precedence than and . However, some might find the parenthesized version clearer than the version without parentheses:

On the other hand, some developers might prefer this latter version of the expression. It’s a matter of personal preference. The point is that you can always use parentheses if you feel that they make your code more readable, even if they aren’t necessary to change the order of evaluation.

So far, you’ve learned that a single equal sign ( = ) represents the assignment operator and allows you to assign a value to a variable. Having a right-hand operand that contains other variables is perfectly valid, as you’ve also learned. In particular, the expression to the right of the assignment operator can include the same variable that’s on the left of the operand.

That last sentence may sound confusing, so here’s an example that clarifies the point:

In this example, total is an accumulator variable that you use to accumulate successive values. You should read this example as total is equal to the current value of total plus 5 . This expression effectively increases the value of total , which is now 15 .

Note that this type of assignment only makes sense if the variable in question already has a value. If you try the assignment with an undefined variable, then you get an error:

In this example, the count variable isn’t defined before the assignment, so it doesn’t have a current value. In consequence, Python raises a NameError exception to let you know about the issue.

This type of assignment helps you create accumulators and counter variables, for example. Therefore, it’s quite a common task in programming. As in many similar cases, Python offers a more convenient solution. It supports a shorthand syntax called augmented assignment :

In the highlighted line, you use the augmented addition operator ( += ). With this operator, you create an assignment that’s fully equivalent to total = total + 5 .

Python supports many augmented assignment operators. In general, the syntax for this type of assignment looks something like this:

Note that the dollar sign ( $ ) isn’t a valid Python operator. In this example, it’s a placeholder for a generic operator. The above statement works as follows:

  • Evaluate expression to produce a value.
  • Run the operation defined by the operator that prefixes the assignment operator ( = ), using the current value of variable and the return value of expression as operands.
  • Assign the resulting value back to variable .

The table below shows a summary of the augmented operators for arithmetic operations:

Operator Description Sample Expression Equivalent Expression
Adds the right operand to the left operand and stores the result in the left operand
Subtracts the right operand from the left operand and stores the result in the left operand
Multiplies the right operand with the left operand and stores the result in the left operand
Divides the left operand by the right operand and stores the result in the left operand
Performs of the left operand by the right operand and stores the result in the left operand
Finds the remainder of dividing the left operand by the right operand and stores the result in the left operand
Raises the left operand to the power of the right operand and stores the result in the left operand

As you can conclude from this table, all the arithmetic operators have an augmented version in Python. You can use these augmented operators as a shortcut when creating accumulators, counters, and similar objects.

Did the augmented arithmetic operators look neat and useful to you? The good news is that there are more. You also have augmented bitwise operators in Python:

Operator Operation Example Equivalent
Augmented bitwise AND ( )
Augmented bitwise OR ( )
Augmented bitwise XOR ( )
Augmented bitwise right shift
Augmented bitwise left shift

Finally, the concatenation and repetition operators have augmented variations too. These variations behave differently with mutable and immutable data types:

Operator Description Example
• Runs an augmented concatenation operation on the target sequence.
• Mutable sequences are updated in place.
• If the sequence is immutable, then a new sequence is created and assigned back to the target name.
• Adds to itself times.
• Mutable sequences are updated in place.
• If the sequence is immutable, then a new sequence is created and assigned back to the target name.

Note that the augmented concatenation operator works on two sequences, while the augmented repetition operator works on a sequence and an integer number.

Now you know what operators Python supports and how to use them. Operators are symbols, combinations of symbols, or keywords that you can use along with Python objects to build different types of expressions and perform computations in your code.

In this tutorial, you’ve learned:

  • What Python’s arithmetic operators are and how to use them in arithmetic expressions
  • What Python’s comparison , Boolean , identity , membership operators are
  • How to write expressions using comparison, Boolean, identity, and membership operators
  • Which bitwise operators Python supports and how to use them
  • How to combine and repeat sequences using the concatenation and repetition operators
  • What the augmented assignment operators are and how they work

In other words, you’ve covered an awful lot of ground! If you’d like a handy cheat sheet that can jog your memory on all that you’ve learned, then click the link below:

With all this knowledge about operators, you’re better prepared as a Python developer. You’ll be able to write better and more robust expressions in your code.

🐍 Python Tricks 💌

Get a short & sweet Python Trick delivered to your inbox every couple of days. No spam ever. Unsubscribe any time. Curated by the Real Python team.

Python Tricks Dictionary Merge

About Leodanis Pozo Ramos

Leodanis Pozo Ramos

Leodanis is an industrial engineer who loves Python and software development. He's a self-taught Python developer with 6+ years of experience. He's an avid technical writer with a growing number of articles published on Real Python and other sites.

Each tutorial at Real Python is created by a team of developers so that it meets our high quality standards. The team members who worked on this tutorial are:

Dan Bader

Master Real-World Python Skills With Unlimited Access to Real Python

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

Join us and get access to thousands of tutorials, hands-on video courses, and a community of expert Pythonistas:

What Do You Think?

What’s your #1 takeaway or favorite thing you learned? How are you going to put your newfound skills to use? Leave a comment below and let us know.

Commenting Tips: The most useful comments are those written with the goal of learning from or helping out other students. Get tips for asking good questions and get answers to common questions in our support portal . Looking for a real-time conversation? Visit the Real Python Community Chat or join the next “Office Hours” Live Q&A Session . Happy Pythoning!

Keep Learning

Related Topics: basics python

Keep reading Real Python by creating a free account or signing in:

Already have an account? Sign-In

Almost there! Complete this form and click the button below to gain instant access:

Operators and Expressions in Python (Cheat Sheet)

🔒 No spam. We take your privacy seriously.

python assignment or operator

Learn Python practically and Get Certified .

Popular Tutorials

Popular examples, reference materials, learn python interactively, python introduction.

  • Get Started With Python
  • Your First Python Program
  • Python Comments

Python Fundamentals

  • Python Variables and Literals
  • Python Type Conversion
  • Python Basic Input and Output

Python Operators

Python flow control.

Python if...else Statement

  • Python for Loop
  • Python while Loop
  • Python break and continue
  • Python pass Statement

Python Data types

  • Python Numbers and Mathematics
  • Python List
  • Python Tuple
  • Python String
  • Python Dictionary
  • Python Functions
  • Python Function Arguments
  • Python Variable Scope
  • Python Global Keyword
  • Python Recursion
  • Python Modules
  • Python Package
  • Python Main function

Python Files

  • Python Directory and Files Management
  • Python CSV: Read and Write CSV files
  • Reading CSV files in Python
  • Writing CSV files in Python
  • Python Exception Handling
  • Python Exceptions
  • Python Custom Exceptions

Python Object & Class

  • Python Objects and Classes
  • Python Inheritance
  • Python Multiple Inheritance
  • Polymorphism in Python

Python Operator Overloading

Python Advanced Topics

  • List comprehension
  • Python Lambda/Anonymous Function
  • Python Iterators
  • Python Generators
  • Python Namespace and Scope
  • Python Closures
  • Python Decorators
  • Python @property decorator
  • Python RegEx

Python Date and Time

  • Python datetime
  • Python strftime()
  • Python strptime()
  • How to get current date and time in Python?
  • Python Get Current Time
  • Python timestamp to datetime and vice-versa
  • Python time Module
  • Python sleep()

Additional Topic

Precedence and Associativity of Operators in Python

  • Python Keywords and Identifiers
  • Python Asserts
  • Python Json
  • Python *args and **kwargs

Python Tutorials

Python 3 Tutorial

  • Python Strings
  • Python any()

Operators are special symbols that perform operations on variables and values. For example,

Here, + is an operator that adds two numbers: 5 and 6 .

  • Types of Python Operators

Here's a list of different types of Python operators that we will learn in this tutorial.

  • Arithmetic Operators
  • Assignment Operators
  • Comparison Operators
  • Logical Operators
  • Bitwise Operators
  • Special Operators

1. Python Arithmetic Operators

Arithmetic operators are used to perform mathematical operations like addition, subtraction, multiplication, etc. For example,

Here, - is an arithmetic operator that subtracts two values or variables.

Operator Operation Example
Addition
Subtraction
Multiplication
Division
Floor Division
Modulo
Power

Example 1: Arithmetic Operators in Python

In the above example, we have used multiple arithmetic operators,

  • + to add a and b
  • - to subtract b from a
  • * to multiply a and b
  • / to divide a by b
  • // to floor divide a by b
  • % to get the remainder
  • ** to get a to the power b

2. Python Assignment Operators

Assignment operators are used to assign values to variables. For example,

Here, = is an assignment operator that assigns 5 to x .

Here's a list of different assignment operators available in Python.

Operator Name Example
Assignment Operator
Addition Assignment
Subtraction Assignment
Multiplication Assignment
Division Assignment
Remainder Assignment
Exponent Assignment

Example 2: Assignment Operators

Here, we have used the += operator to assign the sum of a and b to a .

Similarly, we can use any other assignment operators as per our needs.

3. Python Comparison Operators

Comparison operators compare two values/variables and return a boolean result: True or False . For example,

Here, the > comparison operator is used to compare whether a is greater than b or not.

Operator Meaning Example
Is Equal To gives us
Not Equal To gives us
Greater Than gives us
Less Than gives us
Greater Than or Equal To give us
Less Than or Equal To gives us

Example 3: Comparison Operators

Note: Comparison operators are used in decision-making and loops . We'll discuss more of the comparison operator and decision-making in later tutorials.

4. Python Logical Operators

Logical operators are used to check whether an expression is True or False . They are used in decision-making. For example,

Here, and is the logical operator AND . Since both a > 2 and b >= 6 are True , the result is True .

Operator Example Meaning
a b :
only if both the operands are
a b :
if at least one of the operands is
a :
if the operand is and vice-versa.

Example 4: Logical Operators

Note : Here is the truth table for these logical operators.

5. Python Bitwise operators

Bitwise operators act on operands as if they were strings of binary digits. They operate bit by bit, hence the name.

For example, 2 is 10 in binary, and 7 is 111 .

In the table below: Let x = 10 ( 0000 1010 in binary) and y = 4 ( 0000 0100 in binary)

Operator Meaning Example
Bitwise AND x & y = 0 ( )
Bitwise OR x | y = 14 ( )
Bitwise NOT ~x = -11 ( )
Bitwise XOR x ^ y = 14 ( )
Bitwise right shift x >> 2 = 2 ( )
Bitwise left shift x 0010 1000)

6. Python Special operators

Python language offers some special types of operators like the identity operator and the membership operator. They are described below with examples.

  • Identity operators

In Python, is and is not are used to check if two values are located at the same memory location.

It's important to note that having two variables with equal values doesn't necessarily mean they are identical.

Operator Meaning Example
if the operands are identical (refer to the same object)
if the operands are not identical (do not refer to the same object)

Example 4: Identity operators in Python

Here, we see that x1 and y1 are integers of the same values, so they are equal as well as identical. The same is the case with x2 and y2 (strings).

But x3 and y3 are lists. They are equal but not identical. It is because the interpreter locates them separately in memory, although they are equal.

  • Membership operators

In Python, in and not in are the membership operators. They are used to test whether a value or variable is found in a sequence ( string , list , tuple , set and dictionary ).

In a dictionary, we can only test for the presence of a key, not the value.

Operator Meaning Example
if value/variable is in the sequence
if value/variable is in the sequence

Example 5: Membership operators in Python

Here, 'H' is in message , but 'hello' is not present in message (remember, Python is case-sensitive).

Similarly, 1 is key, and 'a' is the value in dictionary dict1 . Hence, 'a' in y returns False .

  • Precedence and Associativity of operators in Python

Table of Contents

  • Introduction
  • Python Arithmetic Operators
  • Python Assignment Operators
  • Python Comparison Operators
  • Python Logical Operators
  • Python Bitwise operators
  • Python Special operators

Write a function to split the restaurant bill among friends.

  • Take the subtotal of the bill and the number of friends as inputs.
  • Calculate the total bill by adding 20% tax to the subtotal and then divide it by the number of friends.
  • Return the amount each friend has to pay, rounded off to two decimal places.

Video: Operators in Python

Sorry about that.

Related Tutorials

Python Tutorial

Assignment Operators

Add and assign, subtract and assign, multiply and assign, divide and assign, floor divide and assign, exponent and assign, modulo and assign.

to

to and assigns the result to

from and assigns the result to

by and assigns the result to

with and assigns the result to ; the result is always a float

with and assigns the result to ; the result will be dependent on the type of values used

to the power of and assigns the result to

is divided by and assigns the result to

For demonstration purposes, let’s use a single variable, num . Initially, we set num to 6. We can apply all of these operators to num and update it accordingly.

Assigning the value of 6 to num results in num being 6.

Expression: num = 6

Adding 3 to num and assigning the result back to num would result in 9.

Expression: num += 3

Subtracting 3 from num and assigning the result back to num would result in 6.

Expression: num -= 3

Multiplying num by 3 and assigning the result back to num would result in 18.

Expression: num *= 3

Dividing num by 3 and assigning the result back to num would result in 6.0 (always a float).

Expression: num /= 3

Performing floor division on num by 3 and assigning the result back to num would result in 2.

Expression: num //= 3

Raising num to the power of 3 and assigning the result back to num would result in 216.

Expression: num **= 3

Calculating the remainder when num is divided by 3 and assigning the result back to num would result in 2.

Expression: num %= 3

We can effectively put this into Python code, and you can experiment with the code yourself! Click the “Run” button to see the output.

The above code is useful when we want to update the same number. We can also use two different numbers and use the assignment operators to apply them on two different values.

theme logo

Logical Python

Effective Python Tutorials

Python Assignment Operators

Introduction to python assignment operators.

Assignment Operators are used for assigning values to the variables. We can also say that assignment operators are used to assign values to the left-hand side operand. For example, in the below table, we are assigning a value to variable ‘a’, which is the left-side operand.

OperatorDescriptionExampleEquivalent
= a = 2a = 2
+= a += 2a = a + 2
-= a -= 2a = a – 2
*= a *= 2a = a * 2
/= a /= 2a = a / 2
%= a %= 2a = a % 2
//= a //= 2a = a // 2
**= a **= 2a = a ** 2
&= a &= 2a = a & 2
|= a |= 2a = a | 2
^= a ^= 2a = a ^ 2
>>= a >>= 2a = a >> 2
<<= a <<= 3a = a << 2

Assignment Operators

Assignment operator.

Equal to sign ‘=’ is used as an assignment operator. It assigns values of the right-hand side expression to the variable or operand present on the left-hand side.

Assigns value 3 to variable ‘a’.

Addition and Assignment Operator

The addition and assignment operator adds left-side and right-side operands and then the sum is assigned to the left-hand side operand.

Below code is equivalent to:  a = a + 2.

Subtraction and Assignment Operator

The subtraction and assignment operator subtracts the right-side operand from the left-side operand, and then the result is assigned to the left-hand side operand.

Below code is equivalent to:  a = a – 2.

Multiplication and Assignment Operator

The multiplication and assignment operator multiplies the right-side operand with the left-side operand, and then the result is assigned to the left-hand side operand.

Below code is equivalent to:  a = a * 2.

Division and Assignment Operator

The division and assignment operator divides the left-side operand with the right-side operand, and then the result is assigned to the left-hand side operand.

Below code is equivalent to:  a = a / 2.

Modulus and Assignment Operator

The modulus and assignment operator divides the left-side operand with the right-side operand, and then the remainder is assigned to the left-hand side operand.

Below code is equivalent to:  a = a % 3.

Floor Division and Assignment Operator

The floor division and assignment operator divides the left side operand with the right side operand. The result is rounded down to the closest integer value(i.e. floor value) and is assigned to the left-hand side operand.

Below code is equivalent to:  a = a // 3.

Exponential and Assignment Operator

The exponential and assignment operator raises the left-side operand to the power of the right-side operand, and the result is assigned to the left-hand side operand.

Below code is equivalent to:  a = a ** 3.

Bitwise AND and Assignment Operator

Bitwise AND and assignment operator performs bitwise AND operation on both the operands and assign the result to the left-hand side operand.

Below code is equivalent to:  a = a & 3.

Illustration:

Numeric ValueBinary Value
2010
3011

Bitwise OR and Assignment Operator

Bitwise OR and assignment operator performs bitwise OR operation on both the operands and assign the result to the left-hand side operand.

Below code is equivalent to:  a = a | 3.

Bitwise XOR and Assignment Operator

Bitwise XOR and assignment operator performs bitwise XOR operation on both the operands and assign the result to the left-hand side operand.

Below code is equivalent to:  a = a ^ 3.

Bitwise Right Shift and Assignment Operator

Bitwise right shift and assignment operator right shifts the left operand by the right operand positions and assigns the result to the left-hand side operand.

Below code is equivalent to:  a = a >> 1.

Numeric InputBinary ValueRight shift by 1Numeric Output
2001000011
4010000102

Bitwise Left Shift and Assignment Operator

Bitwise left shift and assignment operator left shifts the left operand by the right operand positions and assigns the result to the left-hand side operand.

Below code is equivalent to:  a = a << 1.

Numeric InputBitwise ValueLeft shift by 1Numeric Output
2001001004
4010010008

References:

  • Different Assignment operators in Python
  • Assignment Operator in Python
  • Assignment Expressions

Currently Reading :

Currently reading:

Simple assignment operator in Python

Different assignment operators in python.

Rajat Gupta

Software Developer

Published on  Thu Jun 30 2022

Assignment operators in Python are in-fix which are used to perform operations on variables or operands and assign values to the operand on the left side of the operator. They perform arithmetic, logical, and bitwise computations.

Assignment Operators in Python

Add and equal operator, subtract and equal operator, multiply and equal operator, divide and equal operator, modulus and equal operator, double divide and equal operator, exponent assign operator.

  • Bitwise and operator

Bitwise OR operator

  • Bitwise XOR Assignment operator

Bitwise right shift assignment operator

Bitwise left shift assignment operator.

The Simple assignment operator in Python is denoted by = and is used to assign values from the right side of the operator to the value on the left side.

This operator adds the value on the right side to the value on the left side and stores the result in the operand on the left side.

This operator subtracts the value on the right side from the value on the left side and stores the result in the operand on the left side.

The Multiply and equal operator multiplies the right operand with the left operand and then stores the result in the left operand.

It divides the left operand with the right operand and then stores the quotient in the left operand.

The modulus and equal operator finds the modulus from the left and right operand and stores the final result in the left operand.

The double divide and equal or the divide floor and equal operator divides the left operand with the right operand and stores the floor result in the left operand.

It performs exponential or power calculation and assigns value to the left operand.

Bitwise And operator

Performs Bitwise And operation on both variables and stores the result in the left operand. The Bitwise And operation compares the corresponding bits of the left operand to the bits of the right operand and if both bits are 1, the corresponding result is also 1 otherwise 0.

The binary value of 3 is 0011 and the binary value of 5 is 0101, so when the Bitwise And operation is performed on both the values, we get 0001, which is 1 in decimal.

Performs Bitwise OR operator on both variables and stores the result in the left operand. The Bitwise OR operation compares the corresponding bits of the left operand to the bits of the right operand and if any one of the bits is 1, the corresponding result is also 1 otherwise 0.

The binary value of 5 is 0101 and the binary value of 10 is 1010, so when the Bitwise OR operation is performed on both the values, we get 1111, which is 15 in decimal .

Bitwise XOR operator

Performs Bitwise XOR operator on both variables and stores the result in the left operand. The Bitwise XOR operation compares the corresponding bits of the left operand to the bits of the right operand and if only one of the bits is 1, the corresponding result is also 1 otherwise 0.

The binary value of 5 is 0101 and the binary value of 9 is 1001, so when the Bitwise XOR operation is performed on both the values, we get 1100, which is 12 in decimal.

This operator performs a Bitwise right shift on the operands and stores the result in the left operand.

The binary value of 15 is 1111, so when the Bitwise right shift operation is performed on ‘a’, we get 0011, which is 3 in decimal.

This operator performs a Bitwise left shift on the operands and stores the result in the left operand.

The binary value of 15 is 1111, so when the Bitwise left shift operation is performed on ‘a’, we get 11110, which is 30 in decimal.

Closing Thoughts

In this tutorial, we read about different types of assignment operators in Python which are special symbols used to perform arithmetic, logical, and bitwise operations on the operands and store the result in the left side operand. One can read about other Python concepts here .

Related Blogs

4 Ways to implement Python Switch Case Statement

Sanchitee Ladole

Converting String to Float in Python

Ancil Eric D'Silva

Memoization Using Decorators In Python

Harsh Pandey

Harsh Pandey

Python Increment - Everything you need to know

Theano Python Beginner Guide for Getting Started

Taygun Dogan

Taygun Dogan

17 min read

Python Classes And Objects

Browse Flexiple's talent pool

Explore our network of top tech talent. Find the perfect match for your dream team.

  • Programmers
  • React Native
  • Ruby on Rails

Python Tutorial

  • Python Basics
  • Python - Home
  • Python - Overview
  • Python - History
  • Python - Features
  • Python vs C++
  • Python - Hello World Program
  • Python - Application Areas
  • Python - Interpreter
  • Python - Environment Setup
  • Python - Virtual Environment
  • Python - Basic Syntax
  • Python - Variables
  • Python - Data Types
  • Python - Type Casting
  • Python - Unicode System
  • Python - Literals
  • Python - Operators
  • Python - Arithmetic Operators
  • Python - Comparison Operators

Python - Assignment Operators

  • Python - Logical Operators
  • Python - Bitwise Operators
  • Python - Membership Operators
  • Python - Identity Operators
  • Python - Operator Precedence
  • Python - Comments
  • Python - User Input
  • Python - Numbers
  • Python - Booleans
  • Python Control Statements
  • Python - Control Flow
  • Python - Decision Making
  • Python - If Statement
  • Python - If else
  • Python - Nested If
  • Python - Match-Case Statement
  • Python - Loops
  • Python - for Loops
  • Python - for-else Loops
  • Python - While Loops
  • Python - break Statement
  • Python - continue Statement
  • Python - pass Statement
  • Python - Nested Loops
  • Python Functions & Modules
  • Python - Functions
  • Python - Default Arguments
  • Python - Keyword Arguments
  • Python - Keyword-Only Arguments
  • Python - Positional Arguments
  • Python - Positional-Only Arguments
  • Python - Arbitrary Arguments
  • Python - Variables Scope
  • Python - Function Annotations
  • Python - Modules
  • Python - Built in Functions
  • Python Strings
  • Python - Strings
  • Python - Slicing Strings
  • Python - Modify Strings
  • Python - String Concatenation
  • Python - String Formatting
  • Python - Escape Characters
  • Python - String Methods
  • Python - String Exercises
  • Python Lists
  • Python - Lists
  • Python - Access List Items
  • Python - Change List Items
  • Python - Add List Items
  • Python - Remove List Items
  • Python - Loop Lists
  • Python - List Comprehension
  • Python - Sort Lists
  • Python - Copy Lists
  • Python - Join Lists
  • Python - List Methods
  • Python - List Exercises
  • Python Tuples
  • Python - Tuples
  • Python - Access Tuple Items
  • Python - Update Tuples
  • Python - Unpack Tuples
  • Python - Loop Tuples
  • Python - Join Tuples
  • Python - Tuple Methods
  • Python - Tuple Exercises
  • Python Sets
  • Python - Sets
  • Python - Access Set Items
  • Python - Add Set Items
  • Python - Remove Set Items
  • Python - Loop Sets
  • Python - Join Sets
  • Python - Copy Sets
  • Python - Set Operators
  • Python - Set Methods
  • Python - Set Exercises
  • Python Dictionaries
  • Python - Dictionaries
  • Python - Access Dictionary Items
  • Python - Change Dictionary Items
  • Python - Add Dictionary Items
  • Python - Remove Dictionary Items
  • Python - Dictionary View Objects
  • Python - Loop Dictionaries
  • Python - Copy Dictionaries
  • Python - Nested Dictionaries
  • Python - Dictionary Methods
  • Python - Dictionary Exercises
  • Python Arrays
  • Python - Arrays
  • Python - Access Array Items
  • Python - Add Array Items
  • Python - Remove Array Items
  • Python - Loop Arrays
  • Python - Copy Arrays
  • Python - Reverse Arrays
  • Python - Sort Arrays
  • Python - Join Arrays
  • Python - Array Methods
  • Python - Array Exercises
  • Python File Handling
  • Python - File Handling
  • Python - Write to File
  • Python - Read Files
  • Python - Renaming and Deleting Files
  • Python - Directories
  • Python - File Methods
  • Python - OS File/Directory Methods
  • Python - OS Path Methods
  • Object Oriented Programming
  • Python - OOPs Concepts
  • Python - Classes & Objects
  • Python - Class Attributes
  • Python - Class Methods
  • Python - Static Methods
  • Python - Constructors
  • Python - Access Modifiers
  • Python - Inheritance
  • Python - Polymorphism
  • Python - Method Overriding
  • Python - Method Overloading
  • Python - Dynamic Binding
  • Python - Dynamic Typing
  • Python - Abstraction
  • Python - Encapsulation
  • Python - Interfaces
  • Python - Packages
  • Python - Inner Classes
  • Python - Anonymous Class and Objects
  • Python - Singleton Class
  • Python - Wrapper Classes
  • Python - Enums
  • Python - Reflection
  • Python Errors & Exceptions
  • Python - Syntax Errors
  • Python - Exceptions
  • Python - try-except Block
  • Python - try-finally Block
  • Python - Raising Exceptions
  • Python - Exception Chaining
  • Python - Nested try Block
  • Python - User-defined Exception
  • Python - Logging
  • Python - Assertions
  • Python - Built-in Exceptions
  • Python Multithreading
  • Python - Multithreading
  • Python - Thread Life Cycle
  • Python - Creating a Thread
  • Python - Starting a Thread
  • Python - Joining Threads
  • Python - Naming Thread
  • Python - Thread Scheduling
  • Python - Thread Pools
  • Python - Main Thread
  • Python - Thread Priority
  • Python - Daemon Threads
  • Python - Synchronizing Threads
  • Python Synchronization
  • Python - Inter-thread Communication
  • Python - Thread Deadlock
  • Python - Interrupting a Thread
  • Python Networking
  • Python - Networking
  • Python - Socket Programming
  • Python - URL Processing
  • Python - Generics
  • Python Libraries
  • NumPy Tutorial
  • Pandas Tutorial
  • SciPy Tutorial
  • Matplotlib Tutorial
  • Django Tutorial
  • OpenCV Tutorial
  • Python Miscellenous
  • Python - Date & Time
  • Python - Maths
  • Python - Iterators
  • Python - Generators
  • Python - Closures
  • Python - Decorators
  • Python - Recursion
  • Python - Reg Expressions
  • Python - PIP
  • Python - Database Access
  • Python - Weak References
  • Python - Serialization
  • Python - Templating
  • Python - Output Formatting
  • Python - Performance Measurement
  • Python - Data Compression
  • Python - CGI Programming
  • Python - XML Processing
  • Python - GUI Programming
  • Python - Command-Line Arguments
  • Python - Docstrings
  • Python - JSON
  • Python - Sending Email
  • Python - Further Extensions
  • Python - Tools/Utilities
  • Python - GUIs
  • Python Advanced Concepts
  • Python - Abstract Base Classes
  • Python - Custom Exceptions
  • Python - Higher Order Functions
  • Python - Object Internals
  • Python - Memory Management
  • Python - Metaclasses
  • Python - Metaprogramming with Metaclasses
  • Python - Mocking and Stubbing
  • Python - Monkey Patching
  • Python - Signal Handling
  • Python - Type Hints
  • Python - Automation Tutorial
  • Python - Humanize Package
  • Python - Context Managers
  • Python - Coroutines
  • Python - Descriptors
  • Python - Diagnosing and Fixing Memory Leaks
  • Python - Immutable Data Structures
  • Python Useful Resources
  • Python - Questions & Answers
  • Python - Online Quiz
  • Python - Quick Guide
  • Python - Projects
  • Python - Useful Resources
  • Python - Discussion
  • Python Compiler
  • NumPy Compiler
  • Matplotlib Compiler
  • SciPy Compiler
  • Python - Programming Examples
  • Selected Reading
  • UPSC IAS Exams Notes
  • Developer's Best Practices
  • Questions and Answers
  • Effective Resume Writing
  • HR Interview Questions
  • Computer Glossary

Python Assignment Operator

The = (equal to) symbol is defined as assignment operator in Python. The value of Python expression on its right is assigned to a single variable on its left. The = symbol as in programming in general (and Python in particular) should not be confused with its usage in Mathematics, where it states that the expressions on the either side of the symbol are equal.

Example of Assignment Operator in Python

Consider following Python statements −

At the first instance, at least for somebody new to programming but who knows maths, the statement "a=a+b" looks strange. How could a be equal to "a+b"? However, it needs to be reemphasized that the = symbol is an assignment operator here and not used to show the equality of LHS and RHS.

Because it is an assignment, the expression on right evaluates to 15, the value is assigned to a.

In the statement "a+=b", the two operators "+" and "=" can be combined in a "+=" operator. It is called as add and assign operator. In a single statement, it performs addition of two operands "a" and "b", and result is assigned to operand on left, i.e., "a".

Augmented Assignment Operators in Python

In addition to the simple assignment operator, Python provides few more assignment operators for advanced use. They are called cumulative or augmented assignment operators. In this chapter, we shall learn to use augmented assignment operators defined in Python.

Python has the augmented assignment operators for all arithmetic and comparison operators.

Python augmented assignment operators combines addition and assignment in one statement. Since Python supports mixed arithmetic, the two operands may be of different types. However, the type of left operand changes to the operand of on right, if it is wider.

The += operator is an augmented operator. It is also called cumulative addition operator, as it adds "b" in "a" and assigns the result back to a variable.

The following are the augmented assignment operators in Python:

  • Augmented Addition Operator
  • Augmented Subtraction Operator
  • Augmented Multiplication Operator
  • Augmented Division Operator
  • Augmented Modulus Operator
  • Augmented Exponent Operator
  • Augmented Floor division Operator

Augmented Addition Operator (+=)

Following examples will help in understanding how the "+=" operator works −

It will produce the following output −

Augmented Subtraction Operator (-=)

Use -= symbol to perform subtract and assign operations in a single statement. The "a-=b" statement performs "a=a-b" assignment. Operands may be of any number type. Python performs implicit type casting on the object which is narrower in size.

Augmented Multiplication Operator (*=)

The "*=" operator works on similar principle. "a*=b" performs multiply and assign operations, and is equivalent to "a=a*b". In case of augmented multiplication of two complex numbers, the rule of multiplication as discussed in the previous chapter is applicable.

Augmented Division Operator (/=)

The combination symbol "/=" acts as divide and assignment operator, hence "a/=b" is equivalent to "a=a/b". The division operation of int or float operands is float. Division of two complex numbers returns a complex number. Given below are examples of augmented division operator.

Augmented Modulus Operator (%=)

To perform modulus and assignment operation in a single statement, use the %= operator. Like the mod operator, its augmented version also is not supported for complex number.

Augmented Exponent Operator (**=)

The "**=" operator results in computation of "a" raised to "b", and assigning the value back to "a". Given below are some examples −

Augmented Floor division Operator (//=)

For performing floor division and assignment in a single statement, use the "//=" operator. "a//=b" is equivalent to "a=a//b". This operator cannot be used with complex numbers.

Python Operators: Arithmetic, Assignment, Comparison, Logical, Identity, Membership, Bitwise

Operators are special symbols that perform some operation on operands and returns the result. For example, 5 + 6 is an expression where + is an operator that performs arithmetic add operation on numeric left operand 5 and the right side operand 6 and returns a sum of two operands as a result.

Python includes the operator module that includes underlying methods for each operator. For example, the + operator calls the operator.add(a,b) method.

Above, expression 5 + 6 is equivalent to the expression operator.add(5, 6) and operator.__add__(5, 6) . Many function names are those used for special methods, without the double underscores (dunder methods). For backward compatibility, many of these have functions with the double underscores kept.

Python includes the following categories of operators:

Arithmetic Operators

Assignment operators, comparison operators, logical operators, identity operators, membership test operators, bitwise operators.

Arithmetic operators perform the common mathematical operation on the numeric operands.

The arithmetic operators return the type of result depends on the type of operands, as below.

  • If either operand is a complex number, the result is converted to complex;
  • If either operand is a floating point number, the result is converted to floating point;
  • If both operands are integers, then the result is an integer and no conversion is needed.

The following table lists all the arithmetic operators in Python:

Operation Operator Function Example in Python Shell
Sum of two operands + operator.add(a,b)
Left operand minus right operand - operator.sub(a,b)
* operator.mul(a,b)
Left operand raised to the power of right ** operator.pow(a,b)
/ operator.truediv(a,b)
equivilant to // operator.floordiv(a,b)
Reminder of % operator.mod(a, b)

The assignment operators are used to assign values to variables. The following table lists all the arithmetic operators in Python:

Operator Function Example in Python Shell
=
+= operator.iadd(a,b)
-= operator.isub(a,b)
*= operator.imul(a,b)
/= operator.itruediv(a,b)
//= operator.ifloordiv(a,b)
%= operator.imod(a, b)
&= operator.iand(a, b)
|= operator.ior(a, b)
^= operator.ixor(a, b)
>>= operator.irshift(a, b)
<<= operator.ilshift(a, b)

The comparison operators compare two operands and return a boolean either True or False. The following table lists comparison operators in Python.

Operator Function Description Example in Python Shell
> operator.gt(a,b) True if the left operand is higher than the right one
< operator.lt(a,b) True if the left operand is lower than right one
== operator.eq(a,b) True if the operands are equal
!= operator.ne(a,b) True if the operands are not equal
>= operator.ge(a,b) True if the left operand is higher than or equal to the right one
<= operator.le(a,b) True if the left operand is lower than or equal to the right one

The logical operators are used to combine two boolean expressions. The logical operations are generally applicable to all objects, and support truth tests, identity tests, and boolean operations.

Operator Description Example
and True if both are true
or True if at least one is true
not Returns True if an expression evalutes to false and vice-versa

The identity operators check whether the two objects have the same id value e.i. both the objects point to the same memory location.

Operator Function Description Example in Python Shell
is operator.is_(a,b) True if both are true
is not operator.is_not(a,b) True if at least one is true

The membership test operators in and not in test whether the sequence has a given item or not. For the string and bytes types, x in y is True if and only if x is a substring of y .

Operator Function Description Example in Python Shell
in operator.contains(a,b) Returns True if the sequence contains the specified item else returns False.
not in not operator.contains(a,b) Returns True if the sequence does not contains the specified item, else returns False.

Bitwise operators perform operations on binary operands.

Operator Function Description Example in Python Shell
& operator.and_(a,b) Sets each bit to 1 if both bits are 1.
| operator.or_(a,b) Sets each bit to 1 if one of two bits is 1.
^ operator.xor(a,b) Sets each bit to 1 if only one of two bits is 1.
~ operator.invert(a) Inverts all the bits.
<< operator.lshift(a,b) Shift left by pushing zeros in from the right and let the leftmost bits fall off.
>> operator.rshift(a,b) Shift right by pushing copies of the leftmost bit in from the left, and let the rightmost bits fall off.
  • Compare strings in Python
  • Convert file data to list
  • Convert User Input to a Number
  • Convert String to Datetime in Python
  • How to call external commands in Python?
  • How to count the occurrences of a list item?
  • How to flatten list in Python?
  • How to merge dictionaries in Python?
  • How to pass value by reference in Python?
  • Remove duplicate items from list in Python
  • More Python articles

python assignment or operator

We are a team of passionate developers, educators, and technology enthusiasts who, with their combined expertise and experience, create in -depth, comprehensive, and easy to understand tutorials.We focus on a blend of theoretical explanations and practical examples to encourages hands - on learning. Visit About Us page for more information.

  • Python Questions & Answers
  • Python Skill Test
  • Python Latest Articles

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

Python Tutorial

File handling, python modules, python numpy, python pandas, python matplotlib, python scipy, machine learning, python mysql, python mongodb, python reference, module reference, python how to, python examples, python operators.

Operators are used to perform operations on variables and values.

In the example below, we use the + operator to add together two values:

Python divides the operators in the following groups:

  • Arithmetic operators
  • Assignment operators
  • Comparison operators
  • Logical operators
  • Identity operators
  • Membership operators
  • Bitwise operators

Python Arithmetic Operators

Arithmetic operators are used with numeric values to perform common mathematical operations:

Operator Name Example Try it
+ Addition x + y
- Subtraction x - y
* Multiplication x * y
/ Division x / y
% Modulus x % y
** Exponentiation x ** y
// Floor division x // y

Python Assignment Operators

Assignment operators are used to assign values to variables:

Operator Example Same As Try it
= x = 5 x = 5
+= x += 3 x = x + 3
-= x -= 3 x = x - 3
*= x *= 3 x = x * 3
/= x /= 3 x = x / 3
%= x %= 3 x = x % 3
//= x //= 3 x = x // 3
**= x **= 3 x = x ** 3
&= x &= 3 x = x & 3
|= x |= 3 x = x | 3
^= x ^= 3 x = x ^ 3
>>= x >>= 3 x = x >> 3
<<= x <<= 3 x = x << 3
:= print(x := 3) x = 3
print(x)

Advertisement

Python Comparison Operators

Comparison operators are used to compare two values:

Operator Name Example Try it
== Equal x == y
!= Not equal x != y
> Greater than x > y
< Less than x < y
>= Greater than or equal to x >= y
<= Less than or equal to x <= y

Python Logical Operators

Logical operators are used to combine conditional statements:

Operator Description Example Try it
and  Returns True if both statements are true x < 5 and  x < 10
or Returns True if one of the statements is true x < 5 or x < 4
not Reverse the result, returns False if the result is true not(x < 5 and x < 10)

Python Identity Operators

Identity operators are used to compare the objects, not if they are equal, but if they are actually the same object, with the same memory location:

Operator Description Example Try it
is  Returns True if both variables are the same object x is y
is not Returns True if both variables are not the same object x is not y

Python Membership Operators

Membership operators are used to test if a sequence is presented in an object:

Operator Description Example Try it
in  Returns True if a sequence with the specified value is present in the object x in y
not in Returns True if a sequence with the specified value is not present in the object x not in y

Python Bitwise Operators

Bitwise operators are used to compare (binary) numbers:

Operator Name Description Example Try it
AND Sets each bit to 1 if both bits are 1 x & y
| OR Sets each bit to 1 if one of two bits is 1 x | y
^ XOR Sets each bit to 1 if only one of two bits is 1 x ^ y
~ NOT Inverts all the bits ~x
<< Zero fill left shift Shift left by pushing zeros in from the right and let the leftmost bits fall off x << 2
>> Signed right shift Shift right by pushing copies of the leftmost bit in from the left, and let the rightmost bits fall off x >> 2

Operator Precedence

Operator precedence describes the order in which operations are performed.

Parentheses has the highest precedence, meaning that expressions inside parentheses must be evaluated first:

Multiplication * has higher precedence than addition + , and therefor multiplications are evaluated before additions:

The precedence order is described in the table below, starting with the highest precedence at the top:

Operator Description Try it
Parentheses
Exponentiation
    Unary plus, unary minus, and bitwise NOT
      Multiplication, division, floor division, and modulus
  Addition and subtraction
  Bitwise left and right shifts
Bitwise AND
Bitwise XOR
Bitwise OR
                    Comparisons, identity, and membership operators
Logical NOT
AND
OR

If two operators have the same precedence, the expression is evaluated from left to right.

Addition + and subtraction - has the same precedence, and therefor we evaluate the expression from left to right:

Get Certified

COLOR PICKER

colorpicker

Contact Sales

If you want to use W3Schools services as an educational institution, team or enterprise, send us an e-mail: [email protected]

Report Error

If you want to report an error, or if you want to make a suggestion, send us an e-mail: [email protected]

Top Tutorials

Top references, top examples, get certified.

logo

Basic Operators in Python With Examples

' data-src=

Operators are symbols in Python that carry out operations on operands (variables and values). Understanding operators is essential for both simple and complex programming in Python.

This comprehensive guide covers all basic operators in Python with detailed explanations and examples.

1. Arithmetic Operators

Arithmetic operators perform mathematical operations like addition, subtraction, multiplication and division on numbers.

Here are some examples using integers:

The result of division (/) is always a float in Python 3 even if the operands are integers. The floor division operator (//) can be used for division resulting in a whole number.

Here is an example with floats:

We can also perform arithmetic operations between different numeric types like integers and floats:

Some other examples:

2. Assignment Operators

Assignment operators are used to assign values to variables. The standard assignment operator is =.

Here are some examples:

There are also compound assignment operators like += and *= that perform an operation and assignment together.

This makes code shorter and more efficient.

3. Comparison Operators

Comparison operators compare two values and evaluate down to a single Boolean value of either True or False.

These operators can be used on different data types like strings:

4. Logical Operators

Logical operators evaluate Boolean logic between operands. The result is always a Boolean value.

There are three logical operators:

  • and : True only if both operands are true, else False
  • or : True if either one operand is true, else False
  • not : Inverts a True value into False, or a False value into True

Here is an example of chaining logical operators:

5. Identity Operators

Identity operators check if two variables refer to the same object in memory.

There are two identity operators:

  • is : Evaluates if both operands refer to same object
  • is not : Evaluates if operands refer to different objects

Here is an example:

Note that two variables can have the same value, but differ in identity:

6. Membership Operators

Membership operators test whether a value exists in a sequence or collection. There are two membership operators:

  • in : Evaluates to True if value is found in the sequence
  • not in : Evaluates to True if value is not found in the sequence

Here are some examples for lists:

We can also use membership operators on strings:

7. Bitwise Operators

Bitwise operators perform operations at the bit-level, such as checking if a bit is on/off or shifting bits.

Here are some bitwise operators in Python:

Bitwise operators are often used in low-level programming like operating systems, device drivers, etc. where programmers need to manipulate bits in data or access hardware directly.

Summary of Basic Operators

Here is a quick summary table of all basic Python operators we covered:

CategoryOperators
Arithmetic+, -, *, /, %, //, **
Assignment=, +=, -=, *=, /=, %=
Comparison==, !=, >, <, >=, <=
Logicaland, or, not
Identityis, is not
Membershipin, not in
Bitwise&, |, ~, ^, >>, <<

And that covers the basic operators used in Python programming!

' data-src=

Dr. Alex Mitchell is a dedicated coding instructor with a deep passion for teaching and a wealth of experience in computer science education. As a university professor, Dr. Mitchell has played a pivotal role in shaping the coding skills of countless students, helping them navigate the intricate world of programming languages and software development.

Beyond the classroom, Dr. Mitchell is an active contributor to the freeCodeCamp community, where he regularly shares his expertise through tutorials, code examples, and practical insights. His teaching repertoire includes a wide range of languages and frameworks, such as Python, JavaScript, Next.js, and React, which he presents in an accessible and engaging manner.

Dr. Mitchell’s approach to teaching blends academic rigor with real-world applications, ensuring that his students not only understand the theory but also how to apply it effectively. His commitment to education and his ability to simplify complex topics have made him a respected figure in both the university and online learning communities.

Similar Posts

A Quick Guide to Styled Components with Interactive Examples

A Quick Guide to Styled Components with Interactive Examples

Styled components is a popular CSS-in-JS library for React that allows you to write component-level styles…

AWS CLI Tutorial – How to Install, Configure, and Use AWS CLI to Understand Your Resource Environment

AWS CLI Tutorial – How to Install, Configure, and Use AWS CLI to Understand Your Resource Environment

The AWS Command Line Interface (CLI) is an essential tool for efficiently managing resources and infrastructure…

How to Create Auto-Updating Excel Spreadsheets of Stock Market Data with Python, AWS, and IEX Cloud

How to Create Auto-Updating Excel Spreadsheets of Stock Market Data with Python, AWS, and IEX Cloud

Introduction As an active investor, having quick access to up-to-date financial data on stocks of interest…

A Beginner‘s Guide to Docker – How to Create a Client/Server App with Docker Compose

A Beginner‘s Guide to Docker – How to Create a Client/Server App with Docker Compose

As a developer, you‘ve likely heard about Docker and how it makes developing, shipping and running…

190 universities just launched 600 free online courses. Here’s the full list.

190 universities just launched 600 free online courses. Here’s the full list.

Exploring Healthcare and Biochemistry Courses in Depth The recent launch of 600 free online courses across…

A Deeply Detailed but Never Definitive Guide to Mobile Development Architecture with React Native

A Deeply Detailed but Never Definitive Guide to Mobile Development Architecture with React Native

As a full-stack developer with over 10 years of experience building web and mobile apps, the…

  • Trending Now
  • Foundational Courses
  • Data Science
  • Practice Problem
  • Machine Learning
  • System Design
  • DevOps Tutorial

Assignment Operators in Programming

Assignment operators in programming are symbols used to assign values to variables. They offer shorthand notations for performing arithmetic operations and updating variable values in a single step. These operators are fundamental in most programming languages and help streamline code while improving readability.

Table of Content

What are Assignment Operators?

  • Types of Assignment Operators
  • Assignment Operators in C
  • Assignment Operators in C++
  • Assignment Operators in Java
  • Assignment Operators in Python
  • Assignment Operators in C#
  • Assignment Operators in JavaScript
  • Application of Assignment Operators

Assignment operators are used in programming to  assign values  to variables. We use an assignment operator to store and update data within a program. They enable programmers to store data in variables and manipulate that data. The most common assignment operator is the equals sign ( = ), which assigns the value on the right side of the operator to the variable on the left side.

Types of Assignment Operators:

  • Simple Assignment Operator ( = )
  • Addition Assignment Operator ( += )
  • Subtraction Assignment Operator ( -= )
  • Multiplication Assignment Operator ( *= )
  • Division Assignment Operator ( /= )
  • Modulus Assignment Operator ( %= )

Below is a table summarizing common assignment operators along with their symbols, description, and examples:

OperatorDescriptionExamples
= (Assignment)Assigns the value on the right to the variable on the left.  assigns the value 10 to the variable x.
+= (Addition Assignment)Adds the value on the right to the current value of the variable on the left and assigns the result to the variable.  is equivalent to 
-= (Subtraction Assignment)Subtracts the value on the right from the current value of the variable on the left and assigns the result to the variable.  is equivalent to 
*= (Multiplication Assignment)Multiplies the current value of the variable on the left by the value on the right and assigns the result to the variable.  is equivalent to 
/= (Division Assignment)Divides the current value of the variable on the left by the value on the right and assigns the result to the variable.  is equivalent to 
%= (Modulo Assignment)Calculates the modulo of the current value of the variable on the left and the value on the right, then assigns the result to the variable.  is equivalent to 

Assignment Operators in C:

Here are the implementation of Assignment Operator in C language:

Assignment Operators in C++:

Here are the implementation of Assignment Operator in C++ language:

Assignment Operators in Java:

Here are the implementation of Assignment Operator in java language:

Assignment Operators in Python:

Here are the implementation of Assignment Operator in python language:

Assignment Operators in C#:

Here are the implementation of Assignment Operator in C# language:

Assignment Operators in Javascript:

Here are the implementation of Assignment Operator in javascript language:

Application of Assignment Operators:

  • Variable Initialization : Setting initial values to variables during declaration.
  • Mathematical Operations : Combining arithmetic operations with assignment to update variable values.
  • Loop Control : Updating loop variables to control loop iterations.
  • Conditional Statements : Assigning different values based on conditions in conditional statements.
  • Function Return Values : Storing the return values of functions in variables.
  • Data Manipulation : Assigning values received from user input or retrieved from databases to variables.

Conclusion:

In conclusion, assignment operators in programming are essential tools for assigning values to variables and performing operations in a concise and efficient manner. They allow programmers to manipulate data and control the flow of their programs effectively. Understanding and using assignment operators correctly is fundamental to writing clear, efficient, and maintainable code in various programming languages.

Please Login to comment...

Similar reads.

  • Programming

Improve your Coding Skills with Practice

 alt=

What kind of Experience do you want to share?

Navigation Menu

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 You must be signed in to change notification settings

Draft for ECMAScript Error Safe Assignment Operator

arthurfiorette/proposal-safe-assignment-operator

Folders and files.

NameName
19 Commits
workflows workflows

Repository files navigation

Vote on our poll to decide which syntax to use

ECMAScript Safe Assignment Operator Proposal

This proposal is actively under development, and contributions are welcome .

This proposal introduces a new operator, ?= (Safe Assignment) , which simplifies error handling by transforming the result of a function into a tuple. If the function throws an error, the operator returns [error, null] ; if the function executes successfully, it returns [null, result] . This operator is compatible with promises, async functions, and any value that implements the Symbol.result method.

For example, when performing I/O operations or interacting with Promise-based APIs, errors can occur unexpectedly at runtime. Neglecting to handle these errors can lead to unintended behavior and potential security vulnerabilities.

Symbol.result

Usage in functions, usage with objects, recursive handling, using statement, try/catch is not enough, why not data first, polyfilling, using = with functions and objects without symbol.result, similar prior art, what this proposal does not aim to solve, current limitations, help us improve this proposal, inspiration.

  • Simplified Error Handling : Streamline error management by eliminating the need for try-catch blocks.
  • Enhanced Readability : Improve code clarity by reducing nesting and making the flow of error handling more intuitive.
  • Consistency Across APIs : Establish a uniform approach to error handling across various APIs, ensuring predictable behavior.
  • Improved Security : Reduce the risk of overlooking error handling, thereby enhancing the overall security of the code.

How often have you seen code like this?

The issue with the above function is that it can fail silently, potentially crashing your program without any explicit warning.

  • fetch can reject.
  • json can reject.
  • parse can throw.
  • Each of these can produce multiple types of errors.

To address this, we propose the adoption of a new operator, ?= , which facilitates more concise and readable error handling.

Please refer to the What This Proposal Does Not Aim to Solve section to understand the limitations of this proposal.

Proposed Features

This proposal aims to introduce the following features:

Any object that implements the Symbol.result method can be used with the ?= operator.

The Symbol.result method must return a tuple, where the first element represents the error and the second element represents the result.

The Safe Assignment Operator ( ?= )

The ?= operator invokes the Symbol.result method on the object or function on the right side of the operator, ensuring that errors and results are consistently handled in a structured manner.

The result should conform to the format [error, null | undefined] or [null, data] .

When the ?= operator is used within a function, all parameters passed to that function are forwarded to the Symbol.result method.

When the ?= operator is used with an object, no parameters are passed to the Symbol.result method.

The [error, null] tuple is generated upon the first error encountered. However, if the data in a [null, data] tuple also implements a Symbol.result method, it will be invoked recursively.

These behaviors facilitate handling various situations involving promises or objects with Symbol.result methods:

  • async function(): Promise<T>
  • function(): T
  • function(): T | Promise<T>

These cases may involve 0 to 2 levels of nested objects with Symbol.result methods, and the operator is designed to handle all of them correctly.

A Promise is the only other implementation, besides Function , that can be used with the ?= operator.

You may have noticed that await and ?= can be used together, and that's perfectly fine. Due to the Recursive Handling feature, there are no issues with combining them in this way.

The execution will follow this order:

  • getPromise[Symbol.result]() might throw an error when called (if it's a synchronous function returning a promise).
  • If an error is thrown, it will be assigned to error , and execution will halt.
  • If no error is thrown, the result will be assigned to data . Since data is a promise and promises have a Symbol.result method, it will be handled recursively.
  • If the promise rejects , the error will be assigned to error , and execution will stop.
  • If the promise resolves , the result will be assigned to data .

The using or await using statement should also work with the ?= operator. It will perform similarly to a standard using x = y statement.

Note that errors thrown when disposing of a resource are not caught by the ?= operator, just as they are not handled by other current features.

The using management flow is applied only when error is null or undefined , and a is truthy and has a Symbol.dispose method.

The try {} block is rarely useful, as its scoping lacks conceptual significance. It often functions more as a code annotation rather than a control flow construct. Unlike control flow blocks, there is no program state that is meaningful only within a try {} block.

In contrast, the catch {} block is actual control flow, and its scoping is meaningful and relevant.

Using try/catch blocks has two main syntax problems :

In Go, the convention is to place the data variable first, and you might wonder why we don't follow the same approach in JavaScript. In Go, this is the standard way to call a function. However, in JavaScript, we already have the option to use const data = fn() and choose to ignore the error, which is precisely the issue we are trying to address.

If someone is using ?= as their assignment operator, it is because they want to ensure that they handle errors and avoid forgetting them. Placing the data first would contradict this principle, as it prioritizes the result over error handling.

If you want to suppress the error (which is different from ignoring the possibility of a function throwing an error), you can simply do the following:

This approach is much more explicit and readable because it acknowledges that there might be an error, but indicates that you do not care about it.

The above method is also known as "try-catch calaboca" (a Brazilian term) and can be rewritten as:

Complete discussion about this topic at #13 if the reader is interested.

This proposal can be polyfilled using the code provided at polyfill.js .

However, the ?= operator itself cannot be polyfilled directly. When targeting older JavaScript environments, a post-processor should be used to transform the ?= operator into the corresponding [Symbol.result] calls.

If the function or object does not implement a Symbol.result method, the ?= operator should throw a TypeError .

The ?= operator and the Symbol.result proposal do not introduce new logic to the language. In fact, everything this proposal aims to achieve can already be accomplished with current, though verbose and error-prone , language features.

is equivalent to:

This pattern is architecturally present in many languages:

  • Error Handling
  • Result Type
  • The try? Operator
  • try Keyword
  • And many others...

While this proposal cannot offer the same level of type safety or strictness as these languages—due to JavaScript's dynamic nature and the fact that the throw statement can throw anything—it aims to make error handling more consistent and manageable.

Strict Type Enforcement for Errors : The throw statement in JavaScript can throw any type of value. This proposal does not impose type safety on error handling and will not introduce types into the language. It also will not be extended to TypeScript. For more information, see microsoft/typescript#13219 .

Automatic Error Handling : While this proposal facilitates error handling, it does not automatically handle errors for you. You will still need to write the necessary code to manage errors; the proposal simply aims to make this process easier and more consistent.

While this proposal is still in its early stages, we are aware of several limitations and areas that need further development:

Nomenclature for Symbol.result Methods : We need to establish a term for objects and functions that implement Symbol.result methods. Possible terms include Resultable or Errorable , but this needs to be defined.

Usage of this : The behavior of this within the context of Symbol.result has not yet been tested or documented. This is an area that requires further exploration and documentation.

Handling finally Blocks : There are currently no syntax improvements for handling finally blocks. However, you can still use the finally block as you normally would:

This proposal is in its early stages, and we welcome your input to help refine it. Please feel free to open an issue or submit a pull request with your suggestions.

Any contribution is welcome!

  • Arthur Fiorette ( Twitter )
  • This tweet from @LaraVerou
  • Effect TS Error Management
  • The tuple-it npm package, which introduces a similar concept but modifies the Promise and Function prototypes—an approach that is less ideal.
  • The frequent oversight of error handling in JavaScript code.

This proposal is licensed under the MIT License .

Code of conduct

Security policy, sponsor this project, contributors 3.

@arthurfiorette

  • JavaScript 100.0%

How to Fix TypeError: ‘Int’ Object Is Not Callable in Python

TypeError: ‘int’ object is not callable occurs in Python when an integer is called as if it were a function. Here’s how to fix it. 

Reza Lavarian

The Python “TypeError: ‘int’ object is not callable” error occurs when you try to call an integer (int object) as if it was a function. Overriding functions , and calling them later on, is the most common cause for this TypeError.

TypeError: ‘Int’ Object Is Not Callable Solved

The most common cause for TypeError: ‘int’ object is not callable is when you declare a variable with a name that matches the name of a function. Such as defining a variable named sum and calling sum() :

The best solution is to rename the variable, in this case  sum , as follows:

Here’s what the error message looks like:

In the simplest terms, this is what happens:

Additionally, if you accidentally put an extra parenthesis after a function that returns an integer, you’ll get the same TypeError :

In the above example, the round() function returns an int value, and having an extra pair of parenthesis means calling the return integer value like function.

What Causes the TypeError: ‘Int’ Object Is Not Callable? 

There are four common scenarios that create the “‘int’ object is not callable” error in Python. This includes:

  • Declaring variable with a name that’s also the name of a function.
  • Calling a method that’s also the name of a property.
  • Calling a method decorated with @property.
  • Missing a mathematical operator.

More on Python Python List and List Manipulation Tutorial

How to Solve TypeError “‘Int’ Object Is Not Callable” in Python

Let’s explore how to solve each scenario with some examples.

1. Declaring a Variable With a Name That’s Also the Name of a Function 

A Python function is an object like any other built-in object, such as int , float , dict and list , etc. 

All built-in functions are defined in the builtins module and assigned a global name for easier access. For instance, a call to sum() invokes the __builtins__.sum() function internally.

That said, overriding a function, accidentally or on purpose, with another value is technically possible.

For instance, if you define a variable named sum and initialize it with an integer value, sum() will no longer be a function.

If you run the above code, Python will produce a TypeError because 0, the new value of sum, isn’t callable.

This is the first thing to check if you’re calling a function, and you get this error.

You have two ways to fix the issue:

  • Rename the variable sum .
  • Explicitly access the sum function from the builtins module ( __bultins__.sum ).

The second approach isn’t recommended unless you’re developing a module. For instance, if you want to implement an open() function that wraps the built-in open() :

In almost every other case, you should always avoid naming your variables as existing functions and methods. But if you’ve done so, renaming the variable would solve the issue.

So, the above example could be fixed like this:

Here’s another example with the built-in max() function:

To fix it, we rename the max variable name to max_value :

Long story short, you should never use a function name (built-in or user-defined) for your variables.

Now, let’s get to the less common mistakes that lead to this error.

2. Calling a Method That’s Also the Name of a Property

When you define a property in a class constructor, any further definitions of the same name, such as methods, will be ignored.

Since we have a property named code, the method code() is ignored. As a result, any reference to the code will return the property code. Obviously, calling code() is like calling 1() , which raises the TypeError.

To fix it, we need to change the method name:

3. Calling a Method Decorated With @property Decorator 

The @property decorator turns a method into a “getter” for a read-only attribute of the same name.

You need to access the getter method without the parentheses:

More on Python Understanding Duck Typing in Python

4. Missing a Mathematical Operator

In algebra , we can remove the multiplication operator to avoid ambiguity in our expressions. For instance, a × b , can be ab, or a × (b + c) can become a(b + c) .

But not in Python!

In the above example, if you remove the multiplication operator in a × (b + c) , Python’s interpreter would consider it a function call. And since the value of a is numeric, an integer in this case, it’ll raise the TypeError.

So, if you have something like this in your code:

You’d have to change it like so:

Problem solved.

Frequently Asked Questions

What does the typeerror: ‘int’ object is not callable mean in python.

Python produces the TypeError: ‘int’ object is not callable when you try to call an integer (int object) as if it was a function. This most often occurs when you override a function and then attempt to call it later on. The error looks like this:

How do you fix the TypeError: ‘int’ object is not callable in Python?

The most common cause for TypeError: ‘int’ object is when a variable is declared with a name that matches the name of a function. There are two ways to fix it:

Recent Python Algorithms Articles

How to Fix TypeError: 'Str' Object Is Not Callable in Python

  • Stack Overflow for Teams Where developers & technologists share private knowledge with coworkers
  • Advertising & Talent Reach devs & technologists worldwide about your product, service or employer brand
  • OverflowAI GenAI features for Teams
  • OverflowAPI Train & fine-tune LLMs
  • Labs The future of collective knowledge sharing
  • About the company Visit the blog

Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Get early access and see previews of new features.

Is it possible to overload Python assignment?

Is there a magic method that can overload the assignment operator, like __assign__(self, new_value) ?

I'd like to forbid a re-bind for an instance:

Is it possible? Is it insane? Should I be on medicine?

  • assignment-operator
  • magic-methods

Eric's user avatar

  • 3 Use case: people are going to write small scripts using my service API, and I want to prevent them from changing internal data and propagate this change to the next script. –  Caruccio Commented Jun 13, 2012 at 23:39
  • 8 Python explicitly avoids promising that a malicious or ignorant coder will be prevented from access. Other languages allow you to avoid some programmer error due to ignorance, but people have an uncanny ability to code around them. –  msw Commented Jun 13, 2012 at 23:43
  • you could execute that code using exec in d where d is some dictionary. if the code is on module level, every assignment should get sent back to the dictionary. You could either restore your values after execution/check whether values changed, or intercept the dictionary assignment, i.e. replace the dictionary of variables with another object. –  Ant6n Commented Mar 2, 2014 at 1:57
  • Oh no, so it's impossible to simulate VBA behaviour like ScreenUpdating = False on module level –  Winand Commented Sep 1, 2015 at 6:13
  • You can use the __all__ attribute of your module to make it harder for people to export private data. This is a common approach for the Python Standard Library –  Ben Commented Jan 13, 2017 at 22:42

13 Answers 13

The way you describe it is absolutely not possible. Assignment to a name is a fundamental feature of Python and no hooks have been provided to change its behavior.

However, assignment to a member in a class instance can be controlled as you want, by overriding .__setattr__() .

Note that there is a member variable, _locked , that controls whether the assignment is permitted. You can unlock it to update the value.

steveha's user avatar

  • 6 Using @property with a getter but no setter is a similar way to pseudo-overload assignment. –  jtpereyda Commented Dec 16, 2015 at 20:26
  • 4 getattr(self, "_locked", None) instead of self.__dict__.get("_locked") . –  Vedran Šego Commented Apr 9, 2018 at 13:50
  • @VedranŠego I followed your suggestion but used False instead of None . Now if someone deletes the _locked member variable, the .get() call won't raise an exception. –  steveha Commented May 30, 2018 at 6:09
  • 1 @steveha Did it actually raise an exception for you? get defaults to None , unlike getattr which would indeed raise an exception. –  Vedran Šego Commented May 30, 2018 at 9:08
  • 2 Ah, no, I didn't see it raise an exception. Somehow I overlooked that you were suggesting to use getattr() rather than .__dict__.get() . I guess it's better to use getattr() , that's what it's for. –  steveha Commented Jun 7, 2018 at 4:44

No, as assignment is a language intrinsic which doesn't have a modification hook.

msw's user avatar

  • 6 Be assured, this won't happen in Python 4.x. –  Sven Marnach Commented Jun 13, 2012 at 23:40
  • 10 Now I'm tempted to go write a PEP for subclassing and replacing the current scope. –  Mattie Commented Jun 14, 2012 at 11:55

I don't think it's possible. The way I see it, assignment to a variable doesn't do anything to the object it previously referred to: it's just that the variable "points" to a different object now.

However, you can mimic the desired behavior by creating a wrapper object with __setitem__() or __setattr__() methods that raise an exception, and keep the "unchangeable" stuff inside.

Lev Levitsky's user avatar

Inside a module, this is absolutely possible, via a bit of dark magic.

The above example assumes the code resides in a module named tst . You can do this in the repl by changing tst to __main__ .

If you want to protect access through the local module, make all writes to it through tst.var = newval .

Perkins's user avatar

  • I'm not sure if things are different for my version / implementation of python, but for me this works only when trying to access variables form outside of the protected module; i.e. if I protect the module tst and assign Protect() to a variable named var twice within the module tst , no exception is raised. This is in line with the documentation stating that direct assignment utilizes the non-overridable globals dict directly. –  mutableVoid Commented Aug 20, 2021 at 16:21
  • 1 I don't remember which version of python I tested that with. At the time, I was surprised it protected the variable from local changes, but now I cannot replicate that. It is worth noting that tst.var = 5 will throw an exception, but var = 5 will not. –  Perkins Commented Aug 21, 2021 at 17:18

Using the top-level namespace, this is impossible. When you run

It stores the key var and the value 1 in the global dictionary. It is roughly equivalent to calling globals().__setitem__('var', 1) . The problem is that you cannot replace the global dictionary in a running script (you probably can by messing with the stack, but that is not a good idea). However you can execute code in a secondary namespace, and provide a custom dictionary for its globals.

That will fire up a REPL which almost operates normally, but refuses any attempts to set the variable val . You could also use execfile(filename, myg) . Note this doesn't protect against malicious code.

Mad Physicist's user avatar

  • 1 This is dark magic! I fully expected to just find a bunch of answers where people suggest using an object explicitly with an overridden setattr, didn't think about overriding globals and locals with a custom object, wow. This must make PyPy cry though. –  Joseph Garvin Commented Jul 20, 2017 at 6:19
  • @mad-physicist How do I set this to default when I run a python shell? I did try overriding globals for the same. Not sure if I am able to run a python executable to run the above override all the way when I run a python command not in a shell but a code. Any idea how I can do it? –  Gary Commented Nov 29, 2021 at 7:55
  • @Gary. #1) sounds like code smell to me. #2) just run the statements shown here at the beginning of your driver script. –  Mad Physicist Commented Nov 29, 2021 at 13:16
  • @mad-physicist Code smell. No. It is not. There are use cases. But Driver script? I did not understand. I would want to explore that? What is a driver supposed to mean? How do I do that? –  Gary Commented Nov 30, 2021 at 14:51
  • 1 @Gary. You can subclass your module. See here for example: stackoverflow.com/q/4432376/2988730 –  Mad Physicist Commented Dec 1, 2021 at 17:17

I will burn in Python hell, but what's life without a little fun.

Important disclaimers :

  • I only provide this example for fun
  • I'm 100% sure I don't understand this well
  • It might not even be safe to do this, in any sense
  • I don't think this is practical
  • I don't think this is a good idea
  • I don't even want to seriously try to implement this
  • This doesn't work for jupyter (probably ipython too)*

Maybe you can't overload assignment, but you can (at least with Python ~3.9) achieve what you want even at the top-level namespace. It will be hard doing it "properly" for all cases, but here's a small example by hacking audithook s:

And here's the example:

*For Jupyter I found another way that looked a tiny bit cleaner because I parsed the AST instead of the code object:

Kostas Mouratidis's user avatar

  • How do I set this to default when I run a python shell? I did try overriding globals for the same. Not sure if I am able to run a python executable to run the above addautdithook all the way when I run a python command not in a shell but a code. Any idea how I can do it making the audit hook the default? –  Gary Commented Nov 29, 2021 at 8:08
  • Looking at this docs.python.org/3/c-api/sys.html#c.PySys_AddAuditHook docs.python.org/3/library/audit_events.html This Audit Hooks were definitely a fantastic change! It solves my purpose with a little tweak but any way I can completely support python executable runs through command line or third party call all the time with such hooks by default (Python environment default config)? May be I am missing something? Probably another PEP which someone can take and file this. Or is it really needed? –  Gary Commented Nov 29, 2021 at 8:21
  • 1 I'm pretty sure this only works because the Python REPL runs exec on every line, but running python file.py does not. Maybe the "correct" way forward would be to do something like what you're trying by going into C territory, but I'm not familiar with that. Another way could be relying on hooking the import system instead of audit hooks: you could for example read the file your magic code gets imported into and parsing it somehow. That could be fun. –  Kostas Mouratidis Commented Nov 29, 2021 at 10:39
  • yes. The could be one way. But that would not affect the shell or the command in any way. Probably I could do with managing the same hook in every file. But it kind of seems redundant –  Gary Commented Dec 1, 2021 at 16:29

Generally, the best approach I found is overriding __ilshift__ as a setter and __rlshift__ as a getter, being duplicated by the property decorator. It is almost the last operator being resolved just (| & ^) and logical are lower. It is rarely used ( __lrshift__ is less, but it can be taken to account).

Within using of PyPi assign package only forward assignment can be controlled, so actual 'strength' of the operator is lower. PyPi assign package example:

The same with shift:

So <<= operator within getting value at a property is the much more visually clean solution and it is not attempting user to make some reflective mistakes like:

Timofey Kazantsev's user avatar

No there isn't

Think about it, in your example you are rebinding the name var to a new value. You aren't actually touching the instance of Protect.

If the name you wish to rebind is in fact a property of some other entity i.e myobj.var then you can prevent assigning a value to the property/attribute of the entity. But I assume thats not what you want from your example.

Tim Hoffman's user avatar

  • 2 Almost there! I tried to overload the module's __dict__.__setattr__ but module.__dict__ itself is read-only. Also, type(mymodule) == <type 'module'>, and it's not instanceable. –  Caruccio Commented Jun 14, 2012 at 11:53

Yes, It's possible, you can handle __assign__ via modify ast .

pip install assign

You will get

The project is at https://github.com/RyanKung/assign And the simpler gist: https://gist.github.com/RyanKung/4830d6c8474e6bcefa4edd13f122b4df

Ryan Kung's user avatar

  • There's something I don't get... Shouldn't it be print('called with %s' % self) ? –  zezollo Commented Nov 9, 2017 at 16:34
  • 2 There are a few things I don't understand: 1) How (and why?) does the string 'c' end up in the v argument for the __assign__ method? What does your example actually show? It confuses me. 2) When would this be useful? 3) How does this relate to the question? For it to correspond the the code written in the question, wouldn't you need to write b = c , not c = b ? –  HelloGoodbye Commented Nov 12, 2019 at 9:38
  • OP is interested in the case where you unbind a name, not where you bind it. –  Mad Physicist Commented Nov 29, 2021 at 13:23

In the global namespace this is not possible, but you could take advantage of more advanced Python metaprogramming to prevent multiple instances of a the Protect object from being created. The Singleton pattern is good example of this.

In the case of a Singleton you would ensure that once instantiated, even if the original variable referencing the instance is reassigned, that the object would persist. Any subsequent instances would just return a reference to the same object.

Despite this pattern, you would never be able to prevent a global variable name itself from being reassigned.

Community's user avatar

  • A singleton is not enough, since var = 1 does not calls the singleton mechanism. –  Caruccio Commented Jun 14, 2012 at 11:54
  • Understood. I apologize if I wasn't clear. A singleton would prevent further instances of an object (e.g. Protect() ) from being created. There is no way to protect the originally assigned name (e.g. var ). –  jathanism Commented Jun 14, 2012 at 18:11
  • @Caruccio. Unrelated, but 99% of the time, at least in CPython, 1 behaves as a singleton. –  Mad Physicist Commented Sep 18, 2018 at 15:13

As mentioned by other people, there is no way to do it directly. It can be overridden for class members though, which is good for many cases.

As Ryan Kung mentioned, the AST of a package can be instrumented so that all assignments can have a side effect if the class assigned implements specific method(s). Building on his work to handle object creation and attribute assignment cases, the modified code and a full description is available here:

https://github.com/patgolez10/assignhooks

The package can be installed as: pip3 install assignhooks

Example <testmod.py>:

to instrument it, e.g. <test.py>

Will produce:

$ python3 ./test.py

patgolez10's user avatar

Beginning Python 3.8, it is possible to hint that a value is read-only using typing.Final . What this means is that nothing changes at runtime, allowing anyone to change the value, but if you're using any linter that can read type-hints then it's going to warn the user if they attempt to assign it.

This makes for way cleaner code, but it puts full trust in the user to respect it at runtime, making no attempt to stop users from changing values.

Another common pattern is to expose functions instead of module constants, like sys.getrecursionlimit and sys.setrecursionlimit .

Although users can do module.get_x = my_get_x , there's an obvious attempt on the user's part to break it, which can't be fixed. In this way we can prevent people from "accidentally" changing values in our module with minimal complexity.

Simply Beautiful Art's user avatar

A ugly solution is to reassign on destructor. But it's no real overload assignment.

Nuno André's user avatar

Your Answer

Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more

Sign up or log in

Post as a guest.

Required, but never shown

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy .

Not the answer you're looking for? Browse other questions tagged python class methods assignment-operator magic-methods or ask your own question .

  • Featured on Meta
  • We've made changes to our Terms of Service & Privacy Policy - July 2024
  • Bringing clarity to status tag usage on meta sites
  • Feedback requested: How do you use tag hover descriptions for curating and do...

Hot Network Questions

  • UART pin acting as power pin
  • How can I prove both series are equal?
  • shell script to match a function in a file and replace it with another function in another file
  • Is it safe to carry Butane canisters bought at sea level up to 5500m?
  • How to allow just one user to use SSH?
  • GNU grep: This manpage is not compatible with mandoc
  • Just got a new job... huh?
  • are "lie low" and "keep a low profile" interchangeable?
  • Subspace proofs - Sheldon Axler's "Linear Algebra Done Right"
  • Does have subgather command like subequation? (elsevier format) (I wanna 1a,1b,1c)
  • Venus’ LIP period starts today, can we save the Venusians?
  • What if something goes wrong during the seven minutes of terror?
  • Stabilizing an offset wood bunk bed
  • Sci-fi book about humanity warring against aliens that eliminate all species in the galaxy
  • What's the sales pitch for waxing chains?
  • Is the oil level here too high that it needs to be drained or can I leave it?
  • Can I travel with regional trains from operators other than DB if I can "use any train" due to a schedule change?
  • Did the United States have consent from Texas to cede a piece of land that was part of Texas?
  • Tipped Wages: What is a Tip
  • Finite loop runs infinitely
  • Why is there a custom to say "Kiddush Levana" (Moon Blessing) on Motsaei Tisha Be'av
  • Can science inform philosophy?
  • One number grid, two ways to divide it
  • Definition of the electric field

python assignment or operator

IMAGES

  1. Python Operator

    python assignment or operator

  2. 7 Types of Python Operators that will ease your programming

    python assignment or operator

  3. Python Operators (Arithmetic, Logical, Relational, Assignment & Bitwise)

    python assignment or operator

  4. Python Tutorials: Assignment Operators In python

    python assignment or operator

  5. Python Operators and Expressions

    python assignment or operator

  6. Python Operators

    python assignment or operator

COMMENTS

  1. coding style

    This behavior is the basis for a form of the if/else ternary operator: A = Y if X else Z. edited Jan 5, 2012 at 19:40. answered Jan 5, 2012 at 19:12. joaquin. 84.8k 31 143 155. 4. But it may cause to repeat a long parameters where Y = X. For instance: A = my_main_dictionary.my_sub_dictionary.my_value if my_main_dictionary.my_sub_dictionary.my ...

  2. 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.

  3. Assignment Operators in Python

    The Walrus Operator in Python is a new assignment operator which is introduced in Python version 3.8 and higher. This operator is used to assign a value to a variable within an expression. Syntax: a := expression. Example: In this code, we have a Python list of integers. We have used Python Walrus assignment operator within the Python while loop.

  4. Python Assignment Operators

    Python Assignment Operators. Assignment operators are used to assign values to variables: Operator. Example. Same As. Try it. =. x = 5. x = 5.

  5. The Walrus Operator: Python's Assignment Expressions

    Each new version of Python adds new features to the language. Back when Python 3.8 was released, the biggest change was the addition of assignment expressions.Specifically, the := operator gave you a new syntax for assigning variables in the middle of expressions. This operator is colloquially known as the walrus operator.. This tutorial is an in-depth introduction to the walrus operator.

  6. Operators and Expressions in Python

    The assignment operator is one of the most frequently used operators in Python. The operator consists of a single equal sign ( = ), and it operates on two operands. The left-hand operand is typically a variable , while the right-hand operand is an expression.

  7. Python Operators (With Examples)

    Assignment operators are used to assign values to variables. For example, # assign 5 to x x = 5. Here, = is an assignment operator that assigns 5 to x. Here's a list of different assignment operators available in Python.

  8. Python Assignment Operators

    We can apply all of these operators to num and update it accordingly. Assignment. Assigning the value of 6 to num results in num being 6. Expression: num = 6. Add and assign. Adding 3 to num and assigning the result back to num would result in 9. Expression: num += 3. Subtract and assign. Subtracting 3 from num and assigning the result back to ...

  9. Python Assignment Operators

    Multiplication and Assignment Operator. The multiplication and assignment operator multiplies the right-side operand with the left-side operand, and then the result is assigned to the left-hand side operand. Below code is equivalent to: a = a * 2. In [1]: a = 3 a *= 2 print(a) 6.

  10. Different Assignment operators in Python

    Assignment operators in Python are in-fix which are used to perform operations on variables or operands and assign values to the operand on the left side of the operator. They perform arithmetic, logical, and bitwise computations. Assignment Operators in Python. Simple assignment operator in Python; Add and equal operator; Subtract and equal ...

  11. Python

    Python - Assignment Operators - The = (equal to) symbol is defined as assignment operator in Python. The value of Python expression on its right is assigned to a single variable on its left. The = symbol as in programming in general (and Python in particular) should not be confused with its usage in Mathematics, where it states th

  12. Python Operators: Arithmetic, Assignment, Comparison, Logical, Identity

    Python Operators: Arithmetic, Assignment, Comparison, Logical, Identity, Membership, Bitwise. Operators are special symbols that perform some operation on operands and returns the result. For example, 5 + 6 is an expression where + is an operator that performs arithmetic add operation on numeric left operand 5 and the right side operand 6 and ...

  13. PEP 572

    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.

  14. Python Operators

    Python Operators. Operators are used to perform operations on variables and values. In the example below, we use the + operator to add together two values: Example. print(10 + 5) ... Assignment operators are used to assign values to variables: Operator Example Same As Try it = x = 5: x = 5:

  15. Assignment Operator in Python

    The simple assignment operator is the most commonly used operator in Python. It is used to assign a value to a variable. The syntax for the simple assignment operator is: variable = value. Here, the value on the right-hand side of the equals sign is assigned to the variable on the left-hand side. For example.

  16. python

    Note that in Python, unlike C, assignment cannot occur inside expressions. C programmers may grumble about this, but it avoids a common class of problems encountered in C programs: typing = in an expression when == was intended. ... The assignment operator - also known informally as the the walrus operator - was created at 28-Feb-2018 in PEP572 ...

  17. Python Operators

    The Python Operators are used to perform operations on values and variables. These are the special symbols that carry out arithmetic, logical, and bitwise computations. The value the operator operates on is known as the Operand. Here, we will cover Different Assignment operators in Python. Operators Sign Description SyntaxAssignment Operator = Assi

  18. Basic Operators In Python With Examples

    Operators are symbols in Python that carry out operations on operands (variables and values). Understanding operators is essential for both simple and complex. ... Assignment operators are used to assign values to variables. The standard assignment operator is =. Here are some examples:

  19. Assignment Operators in Programming

    Assignment operators are used in programming to assign values to variables. We use an assignment operator to store and update data within a program. They enable programmers to store data in variables and manipulate that data. The most common assignment operator is the equals sign (=), which assigns the value on the right side of the operator to ...

  20. How (Not) To Use Python's Walrus Operator

    The Walrus operator, introduced in Python 3.8, enables assignment within expressions, but requires careful use to maintain readability. And this tutorial will teach you how. By Bala Priya C , KDnuggets Contributing Editor & Technical Content Specialist on August 15, 2024 in Python

  21. arthurfiorette/proposal-safe-assignment-operator

    While this proposal is still in its early stages, we are aware of several limitations and areas that need further development: Nomenclature for Symbol.result Methods: We need to establish a term for objects and functions that implement Symbol.result methods. Possible terms include Resultable or Errorable, but this needs to be defined.. Usage of this: The behavior of this within the context of ...

  22. Does python have an assignment operator for logical or?

    3. Is there any way to to logical-or-assignment in python? Much like a += 5. I would like to be able to do something like this: a = True. a or= time_consuming_func_returning_bool() to avoid calling the time-consuming function. That would be neat. python.

  23. TypeError: 'Int' Object Is Not Callable Solved

    More on Python Understanding Duck Typing in Python. 4. Missing a Mathematical Operator. In algebra, we can remove the multiplication operator to avoid ambiguity in our expressions. For instance, a × b, can be ab, or a × (b + c) can become a(b + c). But not in Python! In the above example, if you remove the multiplication operator in a × (b ...

  24. How does Python's comma operator work during assignment?

    32. Python does not have a "comma operator" as in C. Instead, the comma indicates that a tuple should be constructed. The right-hand side of. a, b = a + b, a. is a tuple with th two items a + b and a. On the left-hand side of an assignment, the comma indicates that sequence unpacking should be performed according to the rules you quoted: a will ...

  25. Is it possible to overload Python assignment?

    101. The way you describe it is absolutely not possible. Assignment to a name is a fundamental feature of Python and no hooks have been provided to change its behavior. However, assignment to a member in a class instance can be controlled as you want, by overriding .__setattr__(). class MyClass(object):