Exercises — Interning
Integer Interning
Section titled “Integer Interning”Exercise 1 — 🟢 Beginner
Predict the output of the following code before running it. Think carefully about the integer cache boundaries:
a = 0b = 0print(a is b) # ?
a = 256b = 256print(a is b) # ?
a = 257b = 257print(a is b) # ?
a = -5b = -5print(a is b) # ?
a = -6b = -6print(a is b) # ?Exercise 2 — 🟢 Beginner
Predict the output and explain why the results differ:
a = 100b = 100c = a + 0 # arithmetic result — is it interned?
print(a is b) # ?print(a is c) # ?print(b is c) # ?print(a == b == c) # ?Exercise 3 — 🟡 Intermediate
Predict the output and explain each result:
# loop counter — inside cache rangetotal = 0for i in range(5): total += i
print(i is 4) # ? — is the loop variable interned?print(i == 4) # ?
# arithmetic result outside cache rangex = 200y = 100z = x + y # 300 — outside cache range
print(z is 300) # ?print(z == 300) # ?String Interning
Section titled “String Interning”Exercise 4 — 🟢 Beginner
Predict the output of the following code. Think about which strings look like identifiers:
a = "hello"b = "hello"print(a is b) # ?
a = "hello_world"b = "hello_world"print(a is b) # ?
a = "hello world" # contains spaceb = "hello world"print(a is b) # ?
a = "hello!" # contains punctuationb = "hello!"print(a is b) # ?
a = "123abc" # starts with digitb = "123abc"print(a is b) # ?Exercise 5 — 🟡 Intermediate
Predict the output and explain why string concatenation affects interning:
a = "hello"b = "world"
c = "helloworld"d = a + b # runtime concatenation — is it interned?
print(c is d) # ?print(c == d) # ?
# now with interningimport syse = sys.intern(a + b)f = sys.intern("helloworld")print(e is f) # ?print(e == f) # ?Exercise 6 — 🟡 Intermediate
Predict the output and explain the difference between compile-time and runtime strings:
# compile time — Python can intern thesea = "user_id"b = "user_id"print(a is b) # ?
# runtime — built dynamicallyprefix = "user"suffix = "_id"c = prefix + suffix # built at runtimeprint(a is c) # ?print(a == c) # ?
# forced interningimport sysd = sys.intern(prefix + suffix)print(a is d) # ?sys.intern() Exercises
Section titled “sys.intern() Exercises”Exercise 7 — 🟢 Beginner
Use sys.intern() to ensure these long strings are shared, then verify with is:
import sys
long_key = "this_is_a_very_long_dictionary_key"
# without interninga = "this_is_a_very_long_dictionary_key"b = "this_is_a_very_long_dictionary_key"print(a is b) # ?
# with interninga = sys.intern("this_is_a_very_long_dictionary_key")b = sys.intern("this_is_a_very_long_dictionary_key")print(a is b) # ?Exercise 8 — 🟡 Intermediate
Rewrite this code to use interned keys and verify all dicts share the same key objects:
# ❌ without interning — 3000 separate key objectsusers = [ {"user_id": i, "user_name": f"user_{i}", "user_email": f"user_{i}@example.com"} for i in range(1000)]
# ✅ rewrite using sys.intern() so all 1000 dicts# share the same 3 key objects
# verify:# list(users[0].keys())[0] is list(users[999].keys())[0] → True# list(users[0].keys())[1] is list(users[999].keys())[1] → True# list(users[0].keys())[2] is list(users[999].keys())[2] → TrueExercise 9 — 🔴 Advanced
Measure the memory difference between interned and non-interned dictionary keys using sys.getsizeof():
import sys
# build two versions of the same dataset# one with interned keys, one without
# expected:# non_interned_size → larger# interned_size → smaller
# hint: use sys.getsizeof() to measure# note: sys.getsizeof() measures the object itself,# not the objects it references —# think about how to measure the total sizeIdentity vs Equality
Section titled “Identity vs Equality”Exercise 10 — 🟢 Beginner
Fix this code that incorrectly uses is to compare values:
# ❌ unreliable — using is for value comparisondef is_valid_status(status): return status is "active" # wrong!
print(is_valid_status("active")) # may be True or False — unreliable
# ✅ fix it so it works correctly regardless of interningExercise 11 — 🟡 Intermediate
Identify all the incorrect uses of is in this code and fix them:
def process_user(user): # ❌ incorrect uses of is if user["status"] is "active": # wrong print("user is active")
if user["age"] is 18: # wrong print("user just turned 18")
if user["name"] is "Alice": # wrong print("hello Alice")
if user["score"] is None: # ? — is this one correct? print("no score yet")
if user["verified"] is True: # ? — is this one correct? print("user is verified")Exercise 12 — 🔴 Advanced
This code uses is for dictionary key lookup optimisation. Identify what is correct, what is wrong, and rewrite it properly:
import sys
# intern the keysSTATUS_KEY = sys.intern("status")NAME_KEY = sys.intern("name")AGE_KEY = sys.intern("age")
users = [ {STATUS_KEY: "active", NAME_KEY: "Alice", AGE_KEY: 30}, {STATUS_KEY: "inactive", NAME_KEY: "Bob", AGE_KEY: 25},]
# ❌ incorrect — mixing is and == incorrectlyfor user in users: if list(user.keys())[0] is STATUS_KEY: # is this correct? if user[STATUS_KEY] is "active": # is this correct? print(f"{user[NAME_KEY]} is active") if user[AGE_KEY] is 30: # is this correct? print(f"{user[NAME_KEY]} is 30")
# Questions:# 1. Which uses of is are correct and which are wrong?# 2. Fix all incorrect uses# 3. Which comparisons benefit from interning and which do not?Try predicting every result before running the code — the goal is to build a precise mental model of when Python reuses objects and when it does not, so you never accidentally rely on interning for correctness.