Trie
Trie (Tree)
A trie is a search tree whose nodes each contain a single string character, and have zero or many children. When traversed depth-first, if a complete word is formed, the node at which the path terminates at may be mapped to a value. The root node is unique from the rest of the nodes, in that it doesn't carry any key, or may carry a special key such as an empty string. Tries may be used to predict auto-complete text, where given a certain prefix, all possible combinations of words to complete the prefix can be generated. They may also be used as map structures such as associative arrays, which when passed a string key, return the corresponding value.
Instantiate a trie object
>>> a_trie = Trie()
Inseert a key and its corresponding value to the trie
>>> a_trie.insert("Hello", 1)
>>> a_trie.insert("World", 2)
Check if a trie is empty
>>> a_trie.is_empty()
False
>>> Trie().is_empty()
True
Get length of some trie
>>> len(a_trie)
10
>>> len(Trie())
0
Get the string representation of some trie
>>> a_trie
(H(e(l(l(o)))), W(o(r(l(d)))))
>>> str(a_trie)
'(H(e(l(l(o)))), W(o(r(l(d)))))'
Get value associated to some key
>>> a_trie["Hello"]
1
>>> a_trie.get_value("World")
2
>>> a_trie["Hello, world"]
Traceback (most recent call last):
...
KeyError: 'key not present in trie'
Replace value associated to some key
>>> a_trie["Hello"] = 100
>>> a_trie.replace("World", 200)
>>> a_trie["Hello, world"] = 300
Traceback (most recent call last):
...
KeyError: 'key not present in trie'
Find all strings with some certain prefix
>>> a_trie.prefix_search("He")
['Hello']
>>> a_trie.prefix_search("qwerty")
[]
Delete a key, and thus its corresponding value too, from the trie
>>> del a_trie["Hello"]
>>> a_trie.delete("World")
>>> del a_trie["Hello, world"]
Traceback (most recent call last):
...
KeyError: 'key not present in trie'
__delitem__(self, key)
special
Alias of delete
Source code in trees/trie.py
def __delitem__(self, key: str) -> None:
"""Alias of delete"""
self.delete(key)
__getitem__(self, key)
special
Alias of get_value
Source code in trees/trie.py
def __getitem__(self, key: str) -> Any:
"""Alias of get_value"""
return self.get_value(key)
__setitem__(self, key, value)
special
Alias of replace
Source code in trees/trie.py
def __setitem__(self, key: str, value: Any) -> None:
"""Alias of replace"""
self.replace(key, value)
delete(self, key)
Delete a key and its corresponding value from the trie
Parameters:
Name | Type | Description | Default |
---|---|---|---|
key |
str |
key to delete |
required |
Source code in trees/trie.py
def delete(self, key: str) -> None:
"""Delete a key and its corresponding value from the trie
:param key: key to delete
"""
def not_found_callable():
raise KeyError("key not present in trie")
_, path = self.__get_node_for_key(key, not_found_callable)
end_of_string_occurrences = 0
while len(path) > 1:
node = path.pop()
previous_node = path[-1]
if node.end_of_string:
if end_of_string_occurrences > 0:
break
end_of_string_occurrences += 1
node.value = None
node.end_of_string = False
if len(node.children) > 0:
break
else:
previous_node.children.remove(node)
self._length -= 1
get_value(self, key)
Return the value associated with a certain key
Parameters:
Name | Type | Description | Default |
---|---|---|---|
key |
str |
key whose value is being sought |
required |
Returns:
Type | Description |
---|---|
Any |
value corresponding to the passed key |
Source code in trees/trie.py
def get_value(self, key: str) -> Any:
"""Return the value associated with a certain key
:param key: key whose value is being sought
:returns: value corresponding to the passed key
"""
def not_found_callable():
raise KeyError("key not present in trie")
current_node, _ = self.__get_node_for_key(key, not_found_callable)
return current_node.value
insert(self, key, value=None)
Insert a key and its corresponding value into the trie
Parameters:
Name | Type | Description | Default |
---|---|---|---|
key |
str |
key to insert |
required |
value |
Any |
value corresponding to the key |
None |
Source code in trees/trie.py
def insert(self, key: str, value: Any = None) -> None:
"""Insert a key and its corresponding value into the trie
:param key: key to insert
:param value: value corresponding to the key
"""
def not_found_callable():
pass
current_node, _ = self.__get_node_for_key(
key, not_found_callable, create_node=True
)
current_node.value = value
current_node.end_of_string = True
is_empty(self)
Return True if trie is empty, else False. Time complexity: O(1).
Returns:
Type | Description |
---|---|
bool |
True if trie is empty, else False |
Source code in trees/trie.py
def is_empty(self) -> bool:
"""Return True if trie is empty, else False. Time complexity: O(1).
:returns: True if trie is empty, else False
"""
return self._length == 0
prefix_search(self, prefix)
Return all the combinations of words that can be formed from the passed prefix, as per to the trie
Parameters:
Name | Type | Description | Default |
---|---|---|---|
prefix |
str |
first part of the words being sought |
required |
Returns:
Type | Description |
---|---|
List[str] |
all the combinations of words that can be formed from the passed prefix |
Source code in trees/trie.py
def prefix_search(self, prefix: str) -> List[str]:
"""Return all the combinations of words that can be formed from the passed prefix, as per to the trie
:param prefix: first part of the words being sought
:returns: all the combinations of words that can be formed from the passed prefix
"""
def not_found_callable():
raise KeyError("key not present in trie")
def get_strings_helper(root_node: Trie._Node, starting_with: str):
children = root_node.children
if root_node.end_of_string:
yield starting_with
for child in children:
for string_data in get_strings_helper(child, starting_with + child.key):
yield string_data
try:
current_node, _ = self.__get_node_for_key(prefix, not_found_callable)
except KeyError:
return []
return [i for i in get_strings_helper(current_node, prefix)]
replace(self, key, value)
Replace the value of a key with the new passed value
Parameters:
Name | Type | Description | Default |
---|---|---|---|
key |
str |
key whose value is being replaced |
required |
value |
Any |
new value that's to replace current value of the passed key |
required |
Source code in trees/trie.py
def replace(self, key: str, value: Any) -> None:
"""Replace the value of a key with the new passed value
:param key: key whose value is being replaced
:param value: new value that's to replace current value of the passed key
"""
def not_found_callable():
raise KeyError("key not present in trie")
current_node, _ = self.__get_node_for_key(key, not_found_callable)
current_node.value = value