HashMap¶
See the original Rust documentation here.
patina.hashmap |
A hash map that wraps Python’s dict with Rust’s HashMap API. |
HashMap (dct, V]] = None) |
|
Entry (table, ~V][K, V], key) |
A view into a single entry into a map, which may either be vacant or occupied. |
OccupiedEntry (table, ~V][K, V], key) |
A view into an occupied entry in a HashMap . |
VacantEntry (table, ~V][K, V], key) |
A view into a vacant entry in HashMap . |
A hash map that wraps Python’s dict
with Rust’s HashMap API.
Examples¶
>>> from patina import HashMap
>>>
>>> book_reviews: HashMap[str, str] = HashMap() # or HashMap.new()
>>>
>>> # Review some books.
>>> book_reviews.insert(
... "Adventures of Huckleberry Finn",
... "My favorite book.",
... )
None_
>>> book_reviews.insert(
... "Grimms' Fairy Tales",
... "Masterpiece.",
... )
None_
>>> book_reviews.insert(
... "Pride and Prejudice",
... "Very enjoyable.",
... )
None_
>>> book_reviews.insert(
... "The Adventures of Sherlock Holmes",
... "Eye lyked it alot.",
... )
None_
>>>
>>> # Check for a specific one.
>>> if not book_reviews.contains_key("Les Misérables"):
... print(
... "We've got {} reviews, but Les Misérables ain't one.".format(
... len(book_reviews)
... )
... )
...
We've got 4 reviews, but Les Misérables ain't one.
>>>
>>> # oops, this review has a lot of spelling mistakes, let's deleted it.
>>> book_reviews.remove("The Adventures of Sherlock Holmes")
Some('Eye lyked it alot.')
>>>
>>> # Look up the values associated with some keys.
>>> to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"]
>>> for book in to_find:
... review = book_reviews.get(book)
... if review.is_some():
... print("{}: {}".format(book, review.unwrap()))
... else:
... print("{} is unreviewed.".format(book))
...
Pride and Prejudice: Very enjoyable.
Alice's Adventure in Wonderland is unreviewed.
>>>
>>> # Look up the value for a key (will raise KeyError if the key is not found).
>>> print("Review for Jane: {}".format(book_reviews["Pride and Prejudice"]))
Review for Jane: Very enjoyable.
>>>
>>> # Iterate over everything.
>>> for book, review in book_reviews:
... print('{}: "{}"'.format(book, review))
...
Adventures of Huckleberry Finn: "My favorite book."
Grimms' Fairy Tales: "Masterpiece."
Pride and Prejudice: "Very enjoyable."
HashMap
also implements an Entry API
, which allows for more complex
methods of getting, setting, updating, and removing keys and their values:
>>> from patina import HashMap
>>>
>>> player_stats = HashMap[str, int]()
>>>
>>> def random_stat_buff() -> int:
... # could actually return some random value here - let's just return some
... # fixed value for now
... return 42
...
>>> # insert a key only if it doesn't exist
>>> player_stats.entry("health").or_insert(100)
Ref(100)
>>>
>>> # insert a key using a function that provides a new value only if it doesn't
>>> # already exist
>>> player_stats.entry("defence").or_insert_with(random_stat_buff)
Ref(42)
>>>
>>> # update a key, guarding against the key possibly not being set
>>> stat = player_stats.entry("attack").or_insert(100)
>>> stat.modify(lambda stat: stat + random_stat_buff())
Ref(142)
HashMap
can be used with any key type that is Hashable
.
>>> from dataclasses import dataclass
>>> from patina import HashMap
>>>
>>> @dataclass(frozen=True) # frozen so dataclass will add a __hash__ impl
... class Viking:
... name: str
... country: str
...
>>> # Use a HashMap to store the vikings' health points.
>>> vikings = HashMap[Viking, int]()
>>>
>>> vikings.insert(Viking("Einar", "Norway"), 25)
None_
>>> vikings.insert(Viking("Olaf", "Denmark"), 24)
None_
>>> vikings.insert(Viking("Harald", "Iceland"), 12)
None_
>>>
>>> # Print the status of the vikings.
>>> for viking, health in vikings:
... print(repr(viking), "has", health, "hp")
...
Viking(name='Einar', country='Norway') has 25 hp
Viking(name='Olaf', country='Denmark') has 24 hp
Viking(name='Harald', country='Iceland') has 12 hp
A HashMap
with fixed list of elements can be initialized from a list:
>>> from patina import HashMap
>>>
>>> timber_resources = HashMap.from_iter(
... [("Norway", 100), ("Denmark", 50), ("Iceland", 10)]
... )
>>> timber_resources
HashMap({'Norway': 100, 'Denmark': 50, 'Iceland': 10})
HashMap¶
-
class
patina.hashmap.
HashMap
(dct: Optional[Dict[K, V]] = None)¶ -
__init__
(dct: Optional[Dict[K, V]] = None)¶ Creates an empty
HashMap
.>>> HashMap[str, int]() HashMap({})
-
keys
() → Iterable[K]¶ An iterator visiting all keys in arbitrary order. The iterator element type is
K
.>>> map = HashMap[str, int]() >>> map.insert("a", 1) None_ >>> map.insert("b", 2) None_ >>> map.insert("c", 3) None_ >>> >>> for key in map.keys(): ... print(key) ... a b c
-
values
() → Iterable[V]¶ An iterator visiting all values in arbitrary order. The iterator element type is
V
.>>> map = HashMap[str, int]() >>> map.insert("a", 1) None_ >>> map.insert("b", 2) None_ >>> map.insert("c", 3) None_ >>> >>> for val in map.values(): ... print(val) ... 1 2 3
-
values_mut
() → Iterable[patina.ref.Ref[~V][V]]¶ An iterator visiting all values mutably in arbitrary order. The iterator element type is
Ref[V]
.>>> map = HashMap[str, int]() >>> map.insert("a", 1) None_ >>> map.insert("b", 2) None_ >>> map.insert("c", 3) None_ >>> >>> for val in map.values_mut(): ... val.modify(lambda v: v + 10) ... Ref(11) Ref(12) Ref(13) >>> for val in map.values(): ... print(val) ... 11 12 13
-
iter
() → Iterable[Tuple[K, V]]¶ An iterator visiting all key-value pairs in arbitrary order. The iterator element type is
Tuple[K, V]
.Equivalent to
iter(map)
.>>> map = HashMap[str, int]() >>> map.insert("a", 1) None_ >>> map.insert("b", 2) None_ >>> map.insert("c", 3) None_ >>> >>> for key, val in map.iter(): ... print("key:", key, "val:", val) ... key: a val: 1 key: b val: 2 key: c val: 3
-
__iter__
()¶ An iterator visiting all key-value pairs in arbitrary order. The iterator element type is
Tuple[K, V]
.>>> map = HashMap[str, int]() >>> map.insert("a", 1) None_ >>> map.insert("b", 2) None_ >>> map.insert("c", 3) None_ >>> >>> for key, val in map: ... print("key:", key, "val:", val) ... key: a val: 1 key: b val: 2 key: c val: 3
-
iter_mut
() → Iterable[Tuple[K, patina.ref.Ref[~V][V]]]¶ An iterator visiting all key-value pairs in arbitrary order, with mutable references to the values. The iterator element type is
Tuple[K, Ref[V]]
.>>> map = HashMap[str, int]() >>> map.insert("a", 1) None_ >>> map.insert("b", 2) None_ >>> map.insert("c", 3) None_ >>> >>> for key, val in map.iter_mut(): ... val.modify(lambda v: v * 2) ... Ref(2) Ref(4) Ref(6) >>> for key, val in map: ... print("key:", key, "val:", val) ... key: a val: 2 key: b val: 4 key: c val: 6
-
len
() → int¶ Returns the number of elements in the map.
Equivalent to
len(map)
.>>> a = HashMap[int, str]() >>> a.len() 0 >>> a.insert(1, "a") None_ >>> a.len() 1
-
__len__
()¶ Returns the number of elements in the map.
>>> a = HashMap[int, str]() >>> len(a) 0 >>> a.insert(1, "a") None_ >>> len(a) 1
-
is_empty
() → bool¶ Returns
True
if the map contains no elements.>>> a = HashMap[int, str]() >>> a.is_empty() True >>> a.insert(1, "a") None_ >>> a.is_empty() False
-
drain
() → Iterable[Tuple[K, V]]¶ Clears the map, returning all key-value pairs as an iterator.
>>> from itertools import islice >>> >>> a = HashMap[int, str]() >>> a.insert(1, "a") None_ >>> a.insert(2, "b") None_ >>> >>> for k, v in islice(a.drain(), 1): ... k == 1 or k == 2 ... v == "a" or v == "b" ... True True >>> a.is_empty() True
-
clear
() → None¶ Clears the map, removing all key-value pairs.
>>> a = HashMap[int, str]() >>> a.insert(1, "a") None_ >>> a.clear() >>> a.is_empty() True
-
entry
(key: K) → patina.hashmap.Entry[~K, ~V][K, V]¶ Gets the given key’s corresponding entry in the map for in-place manipulation.
>>> letters = HashMap[str, int]() >>> >>> for ch in "a short treatise on fungi": ... counter = letters.entry(ch).or_insert(0) ... _ = counter.modify(lambda i: i + 1) ... >>> letters["s"] 2 >>> letters["t"] 3 >>> letters["u"] 1 >>> letters.get("y") None_
-
get
(key: K) → patina.option.Option[~V][V]¶ Returns a reference to the value corresponding to the keys.
>>> map = HashMap[int, str]() >>> map.insert(1, "a") None_ >>> map.get(1) Some('a') >>> map.get(2) None_
-
get_key_value
(key: K) → patina.option.Option[typing.Tuple[~K, ~V]][Tuple[K, V]]¶ Returns the key-value pair corresponding to the supplied key.
>>> map = HashMap[int, str]() >>> map.insert(1, "a") None_ >>> map.get_key_value(1) Some((1, 'a')) >>> map.get_key_value(2) None_
-
__getitem__
(key: K) → V¶ Returns a reference to the value corresponding to the supplied key.
Raises
KeyError
if the key is not present in theHashMap
.>>> map = HashMap[int, str]() >>> map[123] = "abc" >>> map[123] 'abc' >>> map[234] Traceback (most recent call last): ... KeyError: 234
-
contains_key
(key: K) → bool¶ Returns
True
if the map contains a value for the specified key.>>> map = HashMap[int, str]() >>> map.insert(1, "a") None_ >>> map.contains_key(1) True >>> map.contains_key(2) False
-
__contains__
(key: K) → bool¶ Returns
True
if the map contains a value for the specified key.>>> map = HashMap[int, str]() >>> map.insert(1, "a") None_ >>> 1 in map True >>> 2 in map False
-
get_mut
(key: K) → patina.option.Option[patina.ref.Ref[~V]][patina.ref.Ref[~V][V]]¶ Returns a mutable reference to the value corresponding to the key.
>>> map = HashMap[int, str]() >>> map.insert(1, "a") None_ >>> x = map.get_mut(1) >>> if x.is_some(): ... x.unwrap().set("b") ... >>> map[1] 'b'
-
insert
(k: K, v: V) → patina.option.Option[~V][V]¶ Inserts a key-value pair into the map.
If the map did not have this key present,
None_
is returned.If the map did have this key present, the value is updated, and the old value is returned.
>>> map = HashMap[int, str]() >>> map.insert(37, "a") None_ >>> map.is_empty() False >>> >>> map.insert(37, "b") Some('a') >>> map.insert(37, "c") Some('b') >>> map[37] 'c'
-
__setitem__
(key: K, value: V) → None¶ Inserts a key-value pair into the map.
>>> map = HashMap[int, str]() >>> map[37] = "a" >>> map.is_empty() False >>> >>> map[37] = "b" >>> map[37] = "c" >>> map[37] 'c'
-
remove
(key: K) → patina.option.Option[~V][V]¶ Removes a key from the map, returning the value at the key if the key was previously in the map.
>>> map = HashMap[int, str]() >>> map.insert(1, "a") None_ >>> map.remove(1) Some('a') >>> map.remove(1) None_
-
remove_entry
(key: K) → patina.option.Option[typing.Tuple[~K, ~V]][Tuple[K, V]]¶ Removes a key from the map, returning the key and the value if the key was previously in the map.
>>> map = HashMap[int, str]() >>> map.insert(1, "a") None_ >>> map.remove_entry(1) Some((1, 'a')) >>> map.remove(1) None_
-
__delitem__
(key: K) → None¶ Removes a key from the map.
>>> map = HashMap[int, str]() >>> map.insert(1, "a") None_ >>> map.is_empty() False >>> del map[1] >>> map.is_empty() True
-
retain
(f: Callable[[K, patina.ref.Ref[~V][V]], bool]) → None¶ Retains only the elements specified by the predicate.
In other words, remove all pairs
(k, v)
such thatf(k, Ref(v))
returnsFalse
.>>> map = HashMap.from_iter((x, x * 10) for x in range(8)) >>> map.retain(lambda k, _v: k % 2 == 0) >>> len(map) 4
-
extend
(it: Iterable[Tuple[K, V]]) → None¶ Extends a colluction with the contents of an iterator.
-
__eq__
(other)¶ This method tests for
self
andother
values to be equal, and is used by==
.
-
__weakref__
¶ list of weak references to the object (if defined)
-
classmethod
from_iter
(it: Iterable[Tuple[K, V]]) → patina.hashmap.HashMap[~K, ~V][K, V]¶ Creates a value from an iterator.
-
-
class
patina.hashmap.
Entry
(table: patina.hashmap.HashMap[~K, ~V][K, V], key: K)¶ A view into a single entry into a map, which may either be vacant or occupied.
This class is constructed from the
entry()
method onHashMap
.-
or_insert
(default: V) → patina.ref.Ref[~V][V]¶ Ensures a value is in the entry by inserting the default if empty, and returns a mutable reference to the value in the entry.
>>> map = HashMap[str, int]() >>> map.entry("poneyland").or_insert(3) Ref(3) >>> map["poneyland"] 3 >>> map.entry("poneyland").or_insert(10).modify(lambda v: v * 2) Ref(6) >>> map["poneyland"] 6
-
or_insert_with
(default: Callable[[], V]) → patina.ref.Ref[~V][V]¶ Ensures a value is in the entry by inserting the result of the default function if empty, and returns a mutable reference to the value in the entry.
>>> map = HashMap[str, str]() >>> s = "hoho" >>> map.entry("poneyland").or_insert_with(lambda: s) Ref('hoho') >>> map["poneyland"] 'hoho'
-
or_insert_with_key
(default: Callable[[K], V]) → patina.ref.Ref[~V][V]¶ Ensures a value is in the entry by inserting, if empty, the result of the default function. This method allows for generating key-derived values for insertion by providing the default function a reference to the key that was moved during the
.entry(key)
method call (not applicable to Python).>>> map = HashMap[str, int]() >>> map.entry("poneyland").or_insert_with_key(len) Ref(9) >>> map["poneyland"] 9
-
key
() → K¶ Returns a reference to this entry’s key.
>>> map = HashMap[str, int]() >>> map.entry("poneyland").key() 'poneyland'
-
and_modify
(f: Callable[[patina.ref.Ref[~V][V]], None]) → patina.hashmap.Entry[~K, ~V][K, V]¶ Provides in-place mutable access to an occupied entry before any potential inserts into the map.
>>> from patina import Ref >>> >>> map = HashMap[str, int]() >>> >>> def add_one(ref: Ref[int]): ... ref.modify(lambda val: val + 1) ... >>> >>> map.entry("poneyland") \ ... .and_modify(add_one) \ ... .or_insert(42) Ref(42) >>> map["poneyland"] 42 >>> >>> map.entry("poneyland") \ ... .and_modify(add_one) \ ... .or_insert(42) Ref(43) >>> map["poneyland"] 43
-
-
class
patina.hashmap.
OccupiedEntry
(table: patina.hashmap.HashMap[~K, ~V][K, V], key: K)¶ A view into an occupied entry in a
HashMap
. It is part of theEntry
class hierarchy.-
remove_entry
() → Tuple[K, V]¶ Remove the entry from the map.
>>> map = HashMap[str, int]() >>> map.entry("poneyland").or_insert(12) Ref(12) >>> o = map.entry("poneyland") >>> if isinstance(o, OccupiedEntry): ... o.remove_entry() ... ('poneyland', 12) >>> "poneyland" in map False
-
get
() → V¶ Gets a reference to the value in the entry.
>>> map = HashMap[str, int]() >>> map.entry("poneyland").or_insert(12) Ref(12) >>> >>> o = map.entry("poneyland") >>> if isinstance(o, OccupiedEntry): ... print(o.get()) ... 12
-
get_mut
() → patina.ref.Ref[~V][V]¶ Gets a mutable reference to the value in the entry.
>>> map = HashMap[str, int]() >>> map.entry("poneyland").or_insert(12) Ref(12) >>> >>> map["poneyland"] 12 >>> o = map.entry("poneyland") >>> if isinstance(o, OccupiedEntry): ... o.get_mut().modify(lambda v: v + 10) ... o.get_mut().modify(lambda v: v + 2) ... Ref(22) Ref(24) >>> map["poneyland"] 24
-
insert
(value: V) → V¶ Sets the value of the entry, and returns the entry’s old value.
>>> map = HashMap[str, int]() >>> map.entry("poneyland").or_insert(12) Ref(12) >>> >>> o = map.entry("poneyland") >>> if isinstance(o, OccupiedEntry): ... o.insert(15) ... 12 >>> map["poneyland"] 15
-
remove
() → V¶ Takes the value out of the entry, and returns it.
>>> map = HashMap[str, int]() >>> map.entry("poneyland").or_insert(12) Ref(12) >>> >>> o = map.entry("poneyland") >>> if isinstance(o, OccupiedEntry): ... o.remove() ... 12 >>> "poneyland" in map False
-
-
class
patina.hashmap.
VacantEntry
(table: patina.hashmap.HashMap[~K, ~V][K, V], key: K)¶ A view into a vacant entry in
HashMap
. It is part of theEntry
class hierarchy.-
insert
(value: V) → patina.ref.Ref[~V][V]¶ Sets the value of the entry with the
VacantEntry
’s key, and returns a mutable reference to it.>>> map = HashMap[str, int]() >>> o = map.entry("poneyland") >>> if isinstance(o, VacantEntry): ... o.insert(37) ... Ref(37) >>> map["poneyland"] 37
-