8. Collections and iteration¶
Incan has Python-like collections and a familiar for loop.
Coming from Rust?
Incan’s built-in collections compile to the standard Rust collections:
list[T]/List[T]→Vec<T>Vec[T]is accepted as an alias forList[T]in type annotations
dict[K, V]/Dict[K, V]→HashMap<K, V>set[T]/Set[T]→HashSet<T>
(See the prelude type mapping in the imports/modules reference for details.)
Lists¶
def main() -> None:
xs = [1, 2, 3]
println(f"first={xs[0]}")
Use append to add an element at the end, and pop() to remove and return the last element. If you call pop() when the list is empty, the program panics with IndexError: pop from empty list and does not return a default value for the element type (the compiler does not require Default on the element type).
Coming from Python?
Incan lists are close to Python’s: out-of-range indexing and empty list.pop() both surface as IndexError panics with the same canonical messages as CPython where applicable (including pop from empty list).
Dicts¶
def main() -> None:
scores = dict([("alice", 10), ("bob", 7)])
println(f"alice={scores['alice']}")
Sets¶
Use a set to deduplicate values:
def main() -> None:
names = ["Alice", "Bob", "Alice"]
unique = set(names)
println(f"unique_count={len(unique)}")
Iteration with for¶
def main() -> None:
names = ["Alice", "Bob", "Cara"]
for name in names:
println(name)
When you iterate a list stored in a variable, the compiler picks a Rust iteration strategy that matches Incan’s element type. Scalars such as int are stepped by value. For enums, the loop variable is the enum type itself (the compiler uses clone-backed iteration under the hood), so you can compare it to another value of the same enum with == without extra cloning in your source.
Comprehensions (quick transforms)¶
Use comprehensions to build a new list/dict from an existing collection:
def main() -> None:
names = [" Alice ", "Bob", " Cara "]
normalized = [name.strip().lower() for name in names]
counts = {name: 1 for name in normalized}
println(f"normalized={normalized:?}")
println(f"counts={counts:?}")
Try it¶
- Read a list of names, normalize (
strip().lower()), and print them. - Create a
dict[str, int]of counts for how often each name appears. - Use a
setto print only unique names.
One possible solution
def main() -> None:
names = ["Alice", "Alice", "Bob", "Bob", "Cara"]
# 1) Normalize + print
normalized = [name.strip().lower() for name in names]
for name in normalized:
println(name)
# 2) Count occurrences
name_counts: Dict[str, int] = {}
for name in normalized:
current_count = name_counts.get(name).unwrap_or(0)
name_counts[name] = current_count + 1
# 3) Deduplicate + print counts (set iteration order is not guaranteed)
unique = set(normalized)
for name in unique:
println(f"{name}: {name_counts.get(name).unwrap()}")
Where to learn more¶
- Strings and slicing: Strings
- Control flow overview: Control flow
Next¶
Back: 7. Strings and formatting
Next chapter: 9. Enums and better match