Skip to main content

Mojo struct

Dict

struct Dict[K: ExplicitlyCopyable & Movable & Hashable & EqualityComparable, V: ExplicitlyCopyable & Movable, H: Hasher = AHasher[0]]

A container that stores key-value pairs.

The Dict type is Mojo's primary associative collection, similar to Python's dict (dictionary). Unlike a List, which stores elements by index, a Dict stores values associated with unique keys, which enables fast lookups, insertions, and deletions.

You can create a Dict in several ways:

# Empty dictionary
var empty_dict = Dict[String, Int]()

# Dictionary literal syntax
var scores = {"Alice": 95, "Bob": 87, "Charlie": 92}

# Pre-allocated capacity (must be power of 2, >= 8)
var large_dict = Dict[String, Int](power_of_two_initial_capacity=64)

# From separate key and value lists
var keys = ["red", "green", "blue"]
var values = [255, 128, 64]
var colors = Dict[String, Int]()
for i in range(len(keys)):
    colors[keys[i]] = values[i]

Be aware of the following characteristics:

  • Type safety: Both keys and values must be homogeneous types, determined at compile time. This is more restrictive than Python dictionaries but provides better performance:

    var string_to_int = {"count": 42}     # Dict[String, Int]
    var int_to_string = {1: "one"}        # Dict[Int, String]
    var mixed = {"key": 1, 2: "val"}      # Error! Keys must be same type

    However, you can get around this by defining your dictionary key and/or value type as Variant. This is a discriminated union type, meaning it can store any number of different types that can vary at runtime.

  • Value semantics: A Dict is value semantic by default, so assignment creates a deep copy of all key-value pairs:

    var dict1 = {"a": 1, "b": 2}
    var dict2 = dict1        # Deep copy
    dict2["c"] = 3
    print(dict1.__str__())   # => {"a": 1, "b": 2}
    print(dict2.__str__())   # => {"a": 1, "b": 2, "c": 3}

    This is different from Python, where assignment creates a reference to the same dictionary. For more information, read about value semantics.

  • Iteration uses immutable references: When iterating over keys, values, or items, you get immutable references unless you specify ref:

    var inventory = {"apples": 10, "bananas": 5}
    
    # Default behavior creates immutable (read-only) references
    for value in inventory.values():
        value += 1  # error: expression must be mutable
    
    # Using `ref` gets mutable (read-write) references
    for ref value in inventory.values():
        value += 1  # Modify inventory values in-place
    print(inventory.__str__())  # => {"apples": 11, "bananas": 6}
  • KeyError handling: Directly accessing values with the [] operator will raise KeyError if the key is not found:

    var phonebook = {"Alice": "555-0101", "Bob": "555-0102"}
    print(phonebook["Charlie"])  # => KeyError: "Charlie"

    For safe access, you should instead use get():

    var phonebook = {"Alice": "555-0101", "Bob": "555-0102"}
    var phone = phonebook.get("Charlie")
    print(phone.__str__()) if phone else print('phone not found')

Examples:

var phonebook = {"Alice": "555-0101", "Bob": "555-0102"}

# Add/update entries
phonebook["Charlie"] = "555-0103"    # Add new entry
phonebook["Alice"] = "555-0199"      # Update existing entry

# Access directly (unsafe and raises KeyError if key not found)
print(phonebook["Alice"])            # => 555-0199

# Access safely
var phone = phonebook.get("David")   # Returns Optional type
print(phone.or_else("phone not found!"))

# Access safely with default value
phone = phonebook.get("David", "555-0000")
print(phone.__str__())               # => '555-0000'

# Check for keys
if "Bob" in phonebook:
    print("Found Bob")

# Remove (pop) entries
print(phonebook.pop("Charlie"))         # Remove and return: "555-0103"
print(phonebook.pop("Unknown", "N/A"))  # Pop with default

# Iterate over a dictionary
for key in phonebook.keys():
    print("Key:", key)

for value in phonebook.values():
    print("Value:", value)

for item in phonebook.items():
    print(item.key, "=>", item.value)

for key in phonebook:
    print(key, "=>", phonebook[key])

# Number of key-value pairs
print('len:', len(phonebook))        # => len: 2

# Dictionary operations
var backup = phonebook.copy()        # Explicit copy
phonebook.clear()                    # Remove all entries

# Merge dictionaries
var more_numbers = {"David": "555-0104", "Eve": "555-0105"}
backup.update(more_numbers)          # Merge in-place
var combined = backup | more_numbers # Create new merged dict
print(combined.__str__())

Parameters

Implemented traits

AnyType, Boolable, Copyable, Defaultable, ExplicitlyCopyable, Movable, Sized, UnknownDestructibility

Aliases

__copyinit__is_trivial

alias __copyinit__is_trivial = False

__del__is_trivial

alias __del__is_trivial = True

__moveinit__is_trivial

alias __moveinit__is_trivial = True

EMPTY

alias EMPTY = -1

REMOVED

alias REMOVED = -2

Methods

__init__

__init__(out self)

Initialize an empty dictiontary.

__init__(out self, *, power_of_two_initial_capacity: Int)

Initialize an empty dictiontary with a pre-reserved initial capacity.

Examples:

var x = Dict[Int, Int](power_of_two_initial_capacity = 1024)
# Insert (2/3 of 1024) entries without reallocation.

Args:

  • power_of_two_initial_capacity (Int): At least 8, has to be a power of two.

__init__(out self, var keys: List[K], var values: List[V], __dict_literal__: Tuple[])

Constructs a dictionary from the given keys and values.

Args:

  • keys (List): The list of keys to build the dictionary with.
  • values (List): The corresponding values to pair with the keys.
  • dict_literal (Tuple): Tell Mojo to use this method for dict literals.

__copyinit__

__copyinit__(out self, existing: Self)

Copy an existing dictiontary.

Args:

  • existing (Self): The existing dict.

__bool__

__bool__(self) -> Bool

Check if the dictionary is empty or not.

Returns:

Bool: False if the dictionary is empty, True if there is at least one element.

__getitem__

__getitem__(self, key: K) -> ref [*[0,0]._entries._value.value] V

Retrieve a value out of the dictionary.

Args:

  • key (K): The key to retrieve.

Returns:

ref: The value associated with the key, if it's present.

Raises:

"KeyError" if the key isn't present.

__setitem__

__setitem__(mut self, var key: K, var value: V)

Set a value in the dictionary by key.

Args:

  • key (K): The key to associate with the specified value.
  • value (V): The data to store in the dictionary.

__contains__

__contains__(self, key: K) -> Bool

Check if a given key is in the dictionary or not.

Args:

  • key (K): The key to check.

Returns:

Bool: True if the key exists in the dictionary, False otherwise.

__or__

__or__(self, other: Self) -> Self

Merge self with other and return the result as a new dict.

Args:

  • other (Self): The dictionary to merge with.

Returns:

Self: The result of the merge.

__ior__

__ior__(mut self, other: Self)

Merge self with other in place.

Args:

  • other (Self): The dictionary to merge with.

fromkeys

static fromkeys(keys: List[K, hint_trivial_type], value: V) -> Self

Create a new dictionary with keys from list and values set to value.

Args:

  • keys (List): The keys to set.
  • value (V): The value to set.

Returns:

Self: The new dictionary.

static fromkeys(keys: List[K, hint_trivial_type], value: Optional[V] = Optional(None)) -> Dict[K, Optional[V], H]

Create a new dictionary with keys from list and values set to value.

Args:

  • keys (List): The keys to set.
  • value (Optional): The value to set.

Returns:

Dict: The new dictionary.

__iter__

__iter__(ref self) -> _DictKeyIter[K, V, H, self_is_origin]

Iterate over the dict's keys as immutable references.

Returns:

_DictKeyIter: An iterator of immutable references to the dictionary keys.

__reversed__

__reversed__(ref self) -> _DictKeyIter[K, V, H, self_is_origin, False]

Iterate backwards over the dict keys, returning immutable references.

Returns:

_DictKeyIter: A reversed iterator of immutable references to the dict keys.

__len__

__len__(self) -> Int

The number of elements currently stored in the dictionary.

Returns:

Int: The number of elements currently stored in the dictionary.

__str__

__str__[T: ExplicitlyCopyable & Movable & Hashable & EqualityComparable & Representable, U: ExplicitlyCopyable & Movable & Representable, //](self: Dict[T, U]) -> String

Returns a string representation of a Dict.

Notes: Since we can't condition methods on a trait yet, the way to call this method is a bit special. Here is an example below:

var my_dict = Dict[Int, Float64]()
my_dict[1] = 1.1
my_dict[2] = 2.2
dict_as_string = my_dict.__str__()
print(dict_as_string)
# prints "{1: 1.1, 2: 2.2}"

When the compiler supports conditional methods, then a simple String(my_dict) will be enough.

Parameters:

Returns:

String: A string representation of the Dict.

find

find(self, key: K) -> Optional[V]

Find a value in the dictionary by key.

Args:

  • key (K): The key to search for in the dictionary.

Returns:

Optional: An optional value containing a copy of the value if it was present, otherwise an empty Optional.

get

get(self, key: K) -> Optional[V]

Get a value from the dictionary by key.

Args:

  • key (K): The key to search for in the dictionary.

Returns:

Optional: An optional value containing a copy of the value if it was present, otherwise an empty Optional.

get(self, key: K, default: V) -> V

Get a value from the dictionary by key.

Args:

  • key (K): The key to search for in the dictionary.
  • default (V): Default value to return.

Returns:

V: A copy of the value if it was present, otherwise default.

pop

pop(mut self, key: K, var default: V) -> V

Remove a value from the dictionary by key.

Args:

  • key (K): The key to remove from the dictionary.
  • default (V): A default value to return if the key was not found instead of raising.

Returns:

V: The value associated with the key, if it was in the dictionary. If it wasn't, return the provided default value instead.

pop(mut self, key: K) -> V

Remove a value from the dictionary by key.

Args:

  • key (K): The key to remove from the dictionary.

Returns:

V: The value associated with the key, if it was in the dictionary. Raises otherwise.

Raises:

"KeyError" if the key was not present in the dictionary.

popitem

popitem(mut self) -> DictEntry[K, V, H]

Remove and return a (key, value) pair from the dictionary.

Notes: Pairs are returned in LIFO order. popitem() is useful to destructively iterate over a dictionary, as often used in set algorithms. If the dictionary is empty, calling popitem() raises a KeyError.

Returns:

DictEntry: Last dictionary item

Raises:

"KeyError" if the dictionary is empty.

keys

keys(ref self) -> _DictKeyIter[K, V, H, self_is_origin]

Iterate over the dict's keys as immutable references.

Returns:

_DictKeyIter: An iterator of immutable references to the dictionary keys.

values

values(ref self) -> _DictValueIter[K, V, H, self_is_origin]

Iterate over the dict's values as references.

Returns:

_DictValueIter: An iterator of references to the dictionary values.

items

items(ref self) -> _DictEntryIter[K, V, H, self_is_origin]

Iterate over the dict's entries as immutable references.

Examples:

var my_dict = Dict[String, Int]()
my_dict["a"] = 1
my_dict["b"] = 2

for e in my_dict.items():
    print(e.key, e.value)

Notes: These can't yet be unpacked like Python dict items, but you can access the key and value as attributes.

Returns:

_DictEntryIter: An iterator of immutable references to the dictionary entries.

update

update(mut self, other: Self, /)

Update the dictionary with the key/value pairs from other, overwriting existing keys.

Notes: The argument must be positional only.

Args:

  • other (Self): The dictionary to update from.

clear

clear(mut self)

Remove all elements from the dictionary.

setdefault

setdefault(mut self, key: K, var default: V) -> ref [*[0,0]._entries._value.value] V

Get a value from the dictionary by key, or set it to a default if it doesn't exist.

Args:

  • key (K): The key to search for in the dictionary.
  • default (V): The default value to set if the key is not present.

Returns:

ref: The value associated with the key, or the default value if it wasn't present.

Was this page helpful?