Collections¶
Most game data is a collection of values rather than a single value. Python gives you three core built-in collection types, each suited to different situations.
Lists¶
A list is an ordered, mutable sequence of values. The elements do not have to be the same type. Create one with square brackets:
inventory = ["sword", "shield", "health_potion"]
enemies_in_room = [] # empty list, filled during level load
mixed = ["goblin", 3, True, 9.5]
Access elements by index (zero-based). Negative indices count from the end:
first_item = inventory[0] # "sword"
last_item = inventory[-1] # "health_potion"
Lists are mutable — you can change an element after creation:
inventory[1] = "tower_shield" # upgrade the shield
Add and remove elements:
inventory.append("magic_wand") # add to end
inventory.remove("health_potion") # remove first occurrence
sort() sorts the list in place. len() returns the number of
elements. The in operator checks membership:
if "shield" in inventory:
armor_bonus = 10
Iterating a list with a for loop:
for enemy in enemies_in_room:
enemy.update()
If you need to modify elements by index while iterating, combine range
and len:
for i in range(len(enemies_in_room)):
enemies_in_room[i].health -= splash_damage
List operations — + concatenates two lists; * repeats:
wave1 = ["goblin", "goblin"]
wave2 = ["orc"]
full_wave = wave1 + wave2 # ["goblin", "goblin", "orc"]
patrol = ["guard"] * 4 # ["guard", "guard", "guard", "guard"]
Dictionaries¶
A dictionary maps keys to values — you look up a value by name rather than by position. Each key–value pair is called an item:
keybindings = {
"move_forward": "w",
"move_backward": "s",
"jump": "space",
"attack": "mouse1",
}
player_stats = {
"health": 100,
"mana": 50,
"stamina": 75,
}
Access by key — raises KeyError if the key is missing:
jump_key = keybindings["jump"]
current_health = player_stats["health"]
Safe access with a default (no error if the key is absent):
gold = player_stats.get("gold", 0) # returns 0 if "gold" not set
Update a value:
player_stats["health"] -= 20 # take 20 damage
Check whether a key exists with in (note: in checks keys, not
values):
if "shield" in equipped_items:
armor_bonus += 10
Iterate over all items:
for action, key in keybindings.items():
print(f"{action}: {key}")
The in operator on a dictionary uses a hash table internally,
meaning the lookup takes the same amount of time whether the dictionary has
10 items or 10,000. This makes dictionaries the right choice whenever you
need fast lookups by name — ability lookup tables, asset registries, event
dispatch tables.
Tuples¶
A tuple is like a list but immutable — its contents cannot change after creation. This makes tuples appropriate for values that belong together and should never be modified: a fixed coordinate, a color, a key binding pair.
spawn_point = (32.0, 0.0, 5.0) # (x, y, z)
RED = (1.0, 0.0, 0.0, 1.0) # RGBA color
Tuples support indexing and slicing just like lists:
x = spawn_point[0]
print(spawn_point[1:3]) # (0.0, 5.0)
But you cannot modify an element:
spawn_point[0] = 99.0 # TypeError: object doesn't support item assignment
Tuple unpacking assigns each element to a named variable in one step:
x, y, z = spawn_point
Tuples are also hashable, which means they can be used as dictionary keys. A list cannot be a dictionary key; a tuple can. This is useful for grid-based games where you want to look up a cell by its (row, col) position:
tile_data = {
(0, 0): "grass",
(0, 1): "water",
(1, 0): "stone",
}
cell_type = tile_data[(row, col)]