
Python assignment operators are among the most frequently used tools in everyday Python programming. Whether you are storing a number in a variable, updating a running total in a loop, or conditionally assigning a value while testing it, assignment operators are at the heart of the operation. Understanding how each one works — and when to reach for it — makes your code cleaner and more expressive.
This guide covers every Python assignment operator: the plain assignment operator, all augmented (compound) assignment operators, and the walrus operator introduced in Python 3.8. Each section explains what the operator does, why it is useful, shows a runnable code example, and describes what the output means.
The single equals sign = is the foundation of all variable assignment in Python. It binds a name on the left side to the value produced by the expression on the right side. Unlike in mathematics, = does not mean "equals" — it means "take this value and store it under this name."
name = "Alice"
age = 30
score = 98.5
print(name)
print(age)
print(score)
Alice
30
98.5
Each variable now holds its assigned value. You can reassign any variable at any time — Python is dynamically typed, so the variable name simply starts pointing to the new object.
Augmented assignment operators combine a mathematical or bitwise operation with assignment in a single step. Instead of writing x = x + 5, you write x += 5. Both expressions do the same thing, but the augmented form is shorter and signals to the reader that you are updating an existing value rather than creating something new.
Python provides augmented versions for every arithmetic operator and every bitwise operator.
The += operator adds the right-hand value to the current value of the variable and stores the result back in the same variable. It is most commonly used to accumulate a running total.
total = 0
prices = [12.50, 8.00, 22.75, 5.25]
for price in prices:
total += price
print(f"Total cost: ${total:.2f}")
Total cost: $48.50
Each pass through the loop takes the current value of total, adds the current price to it, and saves that new value back into total. This is the standard Python pattern for summing a list without calling the built-in sum function.
The -= operator subtracts the right-hand value from the variable and saves the result. It is natural for tracking a decreasing quantity — a countdown, a budget being spent, or inventory being consumed.
budget = 500.00
expenses = [45.00, 120.00, 30.50, 75.00]
for expense in expenses:
budget -= expense
print(f"Remaining budget: ${budget:.2f}")
Remaining budget: $229.50
Each iteration reduces budget by the current expense. After all four deductions the remaining amount reflects exactly what is left.
The *= operator multiplies the variable by the right-hand value and saves the result. You will see this in compound interest calculations, scaling values, or building a factorial.
value = 1
factors = [2, 3, 4, 5]
for factor in factors:
value *= factor
print(f"Product: {value}")
Product: 120
Starting from 1, the variable is multiplied by 2, then 3, then 4, then 5 — producing 120, which is 5 factorial (5!).
The /= operator divides the variable by the right-hand value, always producing a float result even when both operands are integers. It mirrors the behavior of the / division operator in Python 3.
distance = 1000.0
speed_reduction_steps = [2, 5]
print(f"Original distance: {distance}")
for step in speed_reduction_steps:
distance /= step
print(f"After dividing by {step}: {distance}")
Original distance: 1000.0
After dividing by 2: 500.0
After dividing by 5: 100.0
The //= operator divides the variable by the right-hand value and rounds the result down to the nearest whole number (floor division). The result is always an integer when both operands are integers.
tokens = 47
print(f"Starting tokens: {tokens}")
tokens //= 5
print(f"After floor dividing by 5: {tokens}")
tokens //= 2
print(f"After floor dividing by 2: {tokens}")
Starting tokens: 47
After floor dividing by 5: 9
After floor dividing by 2: 4
47 divided by 5 is 9.4, but floor division drops the decimal and gives 9. Then 9 divided by 2 is 4.5, giving 4. This is useful any time you need integer arithmetic — distributing items evenly, pagination, or converting seconds into whole minutes.
The %= operator divides the variable by the right-hand value and keeps only the remainder. It is invaluable for cyclic logic — wrapping around a range, alternating between states, or checking divisibility.
index = 0
colors = ["red", "green", "blue"]
for item_number in range(1, 10):
print(f"Item {item_number}: {colors[index]}")
index += 1
index %= len(colors)
Item 1: red
Item 2: green
Item 3: blue
Item 4: red
Item 5: green
Item 6: blue
Item 7: red
Item 8: green
Item 9: blue
After reaching the last color, index wraps back to 0 using %=, cycling through the list indefinitely regardless of how many items there are.
The **= operator raises the variable to the power of the right-hand value and saves the result. It is the augmented form of the ** exponentiation operator.
base = 2
print(f"Starting value: {base}")
base **= 3
print(f"After **= 3 (2 cubed): {base}")
base **= 2
print(f"After **= 2 (squared): {base}")
Starting value: 2
After **= 3 (2 cubed): 8
After **= 2 (squared): 64
First 2 is raised to the power of 3 giving 8. Then 8 is squared giving 64. The **= operator makes iterative power calculations concise.
Python includes augmented assignment operators for all four bitwise operations. These work on the binary representation of integers, and are commonly used in systems programming, flag management, and low-level bit manipulation.
The Python documentation on bitwise operators provides the full specification for each one.
&= (Bitwise AND assignment) — Keeps only the bits that are 1 in both operands.
|= (Bitwise OR assignment) — Sets a bit to 1 if it is 1 in either operand.
^= (Bitwise XOR assignment) — Flips a bit if it differs between the two operands.
>>= (Right shift assignment) — Shifts all bits right by the given number of positions.
<<= (Left shift assignment) — Shifts all bits left by the given number of positions.
flags = 0b00001111 # binary: 00001111 = 15
flags &= 0b10101010 # AND: keep overlapping 1-bits
print(f"After &=: {bin(flags)} = {flags}")
flags = 0b00001111
flags |= 0b10100000 # OR: set extra bits
print(f"After |=: {bin(flags)} = {flags}")
flags = 0b00001111
flags ^= 0b00000110 # XOR: flip differing bits
print(f"After ^=: {bin(flags)} = {flags}")
value = 64
value >>= 2 # right shift 2 positions = divide by 4
print(f"After >>=: {value}")
value = 4
value <<= 3 # left shift 3 positions = multiply by 8
print(f"After <<=: {value}")
After &=: 0b1010 = 10
After |=: 0b10101111 = 175
After ^=: 0b1001 = 9
After >>=: 16
After <<=: 32
Each bitwise assignment operator modifies the binary value of the variable in place. Right-shifting by 2 is equivalent to integer division by 4 (2²), and left-shifting by 3 is equivalent to multiplying by 8 (2³).
The walrus operator := was added in Python 3.8 and is officially called the assignment expression operator. Unlike all the other assignment operators, := assigns a value to a variable and simultaneously returns that value as part of an expression.
The most powerful use is inside conditions — you can assign and test in a single line, eliminating an extra variable assignment before the condition.
import re
log_lines = [
"INFO: Server started on port 8080",
"DEBUG: Connection attempt from 192.168.1.5",
"ERROR: Timeout after 30 seconds",
"INFO: Request completed in 120ms",
"ERROR: Disk space below threshold",
]
print("Error lines found:")
for line in log_lines:
if match := re.search(r"ERROR: (.+)", line):
print(f" -> {match.group(1)}")
Error lines found:
-> Timeout after 30 seconds
-> Disk space below threshold
Without the walrus operator you would need to call re.search twice or assign the result before the if statement. With :=, the match result is assigned to match and immediately tested for truthiness in a single expression. If the regex matches, the group is available inside the if block.
The walrus operator is also useful in while loops to read and process data until a sentinel value:
data_stream = [42, 17, 88, 0, 55] # 0 acts as a stop signal
index = 0
while (value := data_stream[index]) != 0:
print(f"Processing value: {value}")
index += 1
print("Stopped at zero sentinel.")
Processing value: 42
Processing value: 17
Processing value: 88
Stopped at zero sentinel.
The walrus operator assigns value from the stream and checks it against 0 in the same while condition. The loop body never runs for the 0 value because the condition is checked first.
Python's plain = assignment operator also supports assigning multiple variables at once through tuple unpacking and the starred assignment form.
x, y, z = 10, 20, 30
print(x, y, z)
first, *rest = [1, 2, 3, 4, 5]
print(first)
print(rest)
a = b = c = 100
print(a, b, c)
10 20 30
1
[2, 3, 4, 5]
100 100 100
Tuple unpacking assigns each value on the right to the corresponding name on the left. The starred form (*rest) captures all remaining elements into a list. Chained assignment (a = b = c = 100) binds all three names to the same value simultaneously.
This example brings together simple assignment, augmented assignment operators, and the walrus operator in a realistic mini-program that reads a list of student scores, filters out low scores using the walrus operator, applies a bonus using +=, and reports a final summary.
import statistics
student_scores = {
"Alice": 78,
"Bob": 45,
"Carol": 91,
"David": 38,
"Eve": 85,
"Frank": 52,
}
PASSING_THRESHOLD = 50
BONUS_POINTS = 5
qualifying_scores = []
for student, score in student_scores.items():
if (adjusted := score + BONUS_POINTS) >= PASSING_THRESHOLD:
qualifying_scores.append(adjusted)
print(f"{student}: {score} + {BONUS_POINTS} bonus = {adjusted} (qualifies)")
else:
print(f"{student}: {score} + {BONUS_POINTS} bonus = {adjusted} (below threshold)")
total = 0
for s in qualifying_scores:
total += s
count = len(qualifying_scores)
average = total / count if count > 0 else 0
print(f"\nQualifying students: {count}")
print(f"Total score sum: {total}")
print(f"Average qualifying score: {average:.2f}")
high_score = qualifying_scores[0]
for s in qualifying_scores[1:]:
if s > high_score:
high_score = s
print(f"Highest qualifying score: {high_score}")
Alice: 78 + 5 bonus = 83 (qualifies)
Bob: 45 + 5 bonus = 50 (qualifies)
Carol: 91 + 5 bonus = 96 (qualifies)
David: 38 + 5 bonus = 43 (below threshold)
Eve: 85 + 5 bonus = 90 (qualifies)
Frank: 52 + 5 bonus = 57 (qualifies)
Qualifying students: 5
Total score sum: 376
Average qualifying score: 75.20
Highest qualifying score: 96
The walrus operator := computes the adjusted score and assigns it in the same expression used to test whether the student qualifies. The += operator accumulates the running total across the qualifying list. The final stats are derived entirely from those two assignment patterns working together.