Python Naming and Multiple Assignment

Choose valid, readable names, assign several variables at once, unpack and swap values, and know when two names share one object.

Lesson 6 of 107Beginner12 min read

Python variable names must start with a letter or underscore, may contain only letters, digits and underscores, and can't be a reserved keyword. Within those rules, the community convention is snake_case. Python also lets you assign several names in one statement:

Python
route, departure = "Harbor loop", "09:40"   # unpacking
berth_a, berth_b = berth_b, berth_a          # swapping

This lesson covers the naming rules and conventions in detail, how unpacking matches values to names, why the swap works without a temporary variable, and the important difference between a = b = [] and a, b = [], []. The examples follow a ferry kiosk managing berths and departures.

Names

Rules (break these and you get a SyntaxError):

  • Use letters, digits and underscores only; no spaces, hyphens or other symbols.
  • Don't start with a digit: 2nd_ferry is invalid, second_ferry is fine.
  • Don't use a keyword such as class, for, return, lambda or None. import keyword; print(keyword.kwlist) lists them all.
  • Names are case-sensitive: berth, Berth and BERTH are three different names.

Conventions from PEP 8 (break these and the code still runs, but reads oddly to other Python developers):

KindStyleExample
Variables, functionssnake_caseseats_remaining
ConstantsUPPER_SNAKE_CASEMAX_PASSENGERS
ClassesCapWordsFerryRoute
Internal useleading underscore_cache

Prefer descriptive names over short ones: seats_remaining beats sr and x. Avoid reusing built-in names such as list, str, sum or id; Python allows it, but the built-in function becomes unavailable in that scope.

Unpacking

Multiple assignment matches each name on the left with the value in the same position on the right:

Python
route, departure, berth = ("Harbor loop", "09:40", 3)

The right side can be any iterable: a tuple, list, string or the result of a function that returns several values. The number of names must equal the number of values, or Python raises ValueError: too many values to unpack (expected 2) or not enough values to unpack.

A starred name collects the leftovers into a list, so the counts no longer need to match exactly:

Python
first, *middle, last = ["09:40", "10:10", "10:40", "11:10"]
print(first, middle, last)   # 09:40 ['10:10', '10:40'] 11:10

Unpacking also works in for loops, which is why for name, time in departures: reads each pair cleanly, and with the underscore convention for values you don't need: route, _, berth = record.

Swapping

a, b = b, a swaps two values in one line. It works because Python evaluates the whole right-hand side first, building a temporary tuple (b's value, a's value), and only then assigns to the targets from left to right.

Doing the same thing with two separate assignments loses data:

Python
a, b = 2, 5
a = b        # a is 5, the original 2 is gone
b = a        # b is 5 too
print(a, b)  # 5 5

Languages without tuple assignment need a third temporary variable (temp = a; a = b; b = temp). In Python the one-liner is both shorter and safer. The same right-side-first rule lets you update related variables together, such as the Fibonacci step a, b = b, a + b, without the new a leaking into the calculation of b.

References

Variables in Python are names that refer to objects; assignment never copies an object. That's invisible for numbers and strings, which can't change, but it matters for lists and dictionaries:

Python
passengers_a = passengers_b = []      # one list, two names
passengers_a.append("Ana")
print(passengers_b)                   # ['Ana']

boat_1, boat_2 = [], []               # two separate lists
boat_1.append("Ben")
print(boat_2)                         # []

Chained assignment a = b = value binds both names to the same object. For an immutable value like 0 or "" that is harmless, because "changing" one name rebinds it to a new object. For a list, every change made through either name is visible through both. a is b confirms whether two names point at the same object. Use separate literals, or .copy(), when you need independent lists.

Independent practice and a worked check

Task: unpack a departure record, swap berths and demonstrate independent passenger lists.

Python
record = ("Island run", "10:15", 1, 4)
route, time, berth_a, berth_b = record
berth_a, berth_b = berth_b, berth_a
print(route, time, berth_a, berth_b)     # Island run 10:15 4 1

shared = also_shared = []
separate_1, separate_2 = [], []
shared.append("Ana")
separate_1.append("Ben")
print(also_shared, separate_2)           # ['Ana'] []
print(shared is also_shared)             # True

The last line proves that chained assignment produced one object. For the worked check, a = b = [] creates two references to one list, not two lists.

Reference and next practice

PEP 8's naming conventions and the reference on assignment statements cover the rules in full. Continue with copying and joining collections and tuples and sets. Practise with the Python exercises and Python quiz.

Naming and Multiple Assignment Summary

  • Names: Identifiers can use letters, digits and underscores but cannot begin with a digit or be a keyword.
  • Unpacking: Multiple assignment matches a sequence of values to several target names.
  • Swapping: The right side is evaluated before its values are assigned to targets.
  • References: Chained assignment gives several names the same object.

Naming and Multiple Assignment Examples

Each example shows the code, the output it produces and what each part does.

Example 1

Naming and Multiple Assignment in a small program

Python
route, departure = ("Harbor loop", "09:40")
a, b = 2, 5
a, b = b, a
print(route, departure)
print(a, b)
Output
Harbor loop 09:40
5 2
Line-by-line explanation
  1. Line 1The tuple's two items are unpacked into route and departure.
  2. Lines 2 to 3The right side (5, 2) is built first, then assigned, so the values swap.
  3. Lines 4 to 5Both pairs print with a space between them.
Example 2

Unpacking departure records

Python
departures = [
    ("Harbor loop", "09:40", 3),
    ("Island run", "10:15", 1),
    ("Night cruise", "21:00", 2),
]

for route, time, berth in departures:
    print(f"{time}  {route:<13} berth {berth}")

first, *others = departures
print("First out:", first[0])
print("Later departures:", len(others))

(_, earliest, _), *_ = sorted(departures, key=lambda d: d[1])
print("Earliest time:", earliest)
Output
09:40  Harbor loop   berth 3
10:15  Island run    berth 1
21:00  Night cruise  berth 2
First out: Harbor loop
Later departures: 2
Earliest time: 09:40
Line-by-line explanation
  1. Line 7Each three-item tuple is unpacked into three loop variables.
  2. Line 10The star collects every record after the first into a list.
  3. Line 14Nested unpacking pulls the time out of the first sorted record; _ ignores the parts we don't need.

Common Naming and Multiple Assignment Mistakes

Creating "two" lists with chained assignment

Don't
morning = evening = []
morning.append("Ana")
print(evening)        # ['Ana']: same list
Do
morning, evening = [], []
morning.append("Ana")
print(evening)        # []

a = b = [] gives one list two names. Create each list separately when they must be independent.

Swapping with two separate assignments

Don't
berth_a = berth_b
berth_b = berth_a     # both now hold the same value
Do
berth_a, berth_b = berth_b, berth_a

Naming and Multiple Assignment in Real Projects

Naming and unpacking in real code

Good names are the cheapest documentation a program can have, and code reviewers comment on them more than almost anything else. Linters such as Ruff and Pylint enforce PEP 8 naming and warn when a variable shadows a built-in like list or id.

Unpacking shows up everywhere: for key, value in d.items(), width, height = image.size, host, port = address, and functions that return several values, such as quotient, remainder = divmod(total, 60). Reading CSV rows into named variables with name, email, plan = row makes the following code far easier to follow than row[0], row[1] and row[2].

Naming and Multiple Assignment FAQ

Can a Python variable name start with an underscore?

Yes. A single leading underscore (_total) conventionally means "internal, don't rely on this from outside". A lone _ is used for values you want to ignore, and in the interactive shell it holds the last result. Names with two leading and trailing underscores, like __init__, are reserved for Python's special methods.

Can I use non-English letters in Python variable names?

Yes. Python 3 allows Unicode letters in identifiers, so prix_unité is valid. Most teams stick to ASCII for compatibility with tools and colleagues, and PEP 8 asks for ASCII names in the standard library.

What does "too many values to unpack" mean?

The right side of an assignment or for loop has more items than there are names on the left. Check the length of the data, add names to match, or use a starred name such as first, *rest = items to collect the extras.

What is the difference between a = b = 0 and a = b = []?

Both bind two names to one object. With 0 that is harmless because integers can't change: a += 1 creates a new object for a and leaves b alone. A list can change in place, so a.append(1) is visible through b too.

How do I swap two variables in Python?

Write a, b = b, a. Python evaluates the right side completely before assigning, so no temporary variable is needed. It works for any number of names, for example rotating three values with a, b, c = b, c, a.

Naming and Multiple Assignment Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Multiple choiceeasy

What does a = b = [] create?

Multiple choicemedium

Which review concern is valid for naming and multiple assignment?

Naming and Multiple Assignment Quiz

2 questions to check what you learned.

  1. What does a = b = [] create?

    • Two independent lists
    • Two references to one list
    • Python ignores the distinction
  2. Which statement correctly describes swapping?

    • The right side is evaluated before its values are assigned to targets.
    • Only the example output matters, not the rule
    • Every operation has the same behavior