For the complete Mojo documentation index, see llms.txt. Markdown versions of all pages are available by appending .md to any URL (e.g. /docs/manual/basics.md).
Counter
struct Counter[V: Movable & Hashable & Equatable & Copyable & ImplicitlyDestructible, H: Hasher = AHasher[SIMD[DType.uint64, 4](0)]]
A container for counting hashable items.
In other languages, similar types to counters include bags, counted sets,
and multisets, although their semantics are normally closer to sets (adding,
removing, intersecting, unions, etc) rather than increasing and decreasing
counts. Mojo's Counter follows Python's model, and adds math versatility by
supporting negative counts.
The value type must implement the KeyElement trait and be Copyable, as
its values are stored in a dictionary as keys and the API copies elements
extensively (e.g., most_common, subtract, merge ops). The keys' uniform
value type must be hashable for use in the
underlying dictionary.
Example:
from std.collections import Counter
var counter = Counter[String]("a", "a", "a", "b", "b", "c", "d", "c", "c")
print(counter["a"]) # prints 3
print(counter["b"]) # prints 2
Parameters
- V (
Movable&Hashable&Equatable&Copyable&ImplicitlyDestructible): The value type to be counted. Must beKeyElementandCopyable. - H (
Hasher): The type of the hasher in the underlying dictionary.
Implemented traits
AnyType,
Boolable,
Copyable,
Defaultable,
Equatable,
ImplicitlyDestructible,
Iterable,
IterableOwned,
Movable,
Sized,
Writable
comptime members
IteratorOwnedType
comptime IteratorOwnedType = _DictKeyIterOwned[V, Int, H]
The owned iterator type for this counter.
IteratorType
comptime IteratorType[iterable_mut: Bool, //, iterable_origin: Origin[mut=iterable_mut]] = _DictKeyIter[V, Int, H, iterable_origin]
The iterator type for this counter.
Parameters
- iterable_mut (
Bool): Whether the iterable is mutable. - iterable_origin (
Origin[mut=iterable_mut]): The origin of the iterable.
Methods
__init__
def __init__(out self)
Create a new, empty Counter object.
def __init__(out self, var *values: V)
Create a new Counter from a list of values.
Example:
from std.collections import Counter
var counter = Counter[String]("a", "a", "a", "b", "b", "c", "d", "c", "c")
print(counter["a"]) # print 3
print(counter["b"]) # print 2
Note:
A counter is not limited to the values used in this initial list.
You may add new keys as needed or remove them with clear or one
of the pop calls.
Args:
- *values (
V): A list of values to count.
def __init__(out self, items: List[V])
Create a Counter from an input iterable.
Example:
from std.collections import Counter
var counter = Counter[String](["a", "a", "a", "b", "b", "c", "d", "c", "c"])
print(counter["a"]) # prints 3
print(counter["b"]) # prints 2
Args:
- items (
List[V]): A list of items to count.
__bool__
def __bool__(self) -> Bool
Check if the Counter is empty or not.
Returns:
Bool: False if the Counter is empty, True otherwise.
__getitem__
def __getitem__(self, key: V) -> Int
Get the count of a key.
Args:
- key (
V): The key to get the count of.
Returns:
Int: The count of the key.
__setitem__
def __setitem__(mut self, value: V, count: Int)
Set a value in the keyword Counter by key.
Args:
- value (
V): The value to associate with the specified count. - count (
Int): The count to store in theCounter.
__neg__
def __neg__(self) -> Self
Subtract from an empty Counter. Strips positive and zero counts, and flips the sign on negative counts.
Returns:
Self: A new Counter with stripped counts and negative counts.
__pos__
def __pos__(self) -> Self
Return a shallow copy of the Counter, stripping non-positive counts.
Returns:
Self: A shallow copy of the Counter.
__eq__
def __eq__(self, other: Self) -> Bool
Check if all counts agree. Missing counts are treated as zero.
Args:
- other (
Self): The otherCounterto compare to.
Returns:
Bool: True if the two Counters are equal, False otherwise.
__contains__
def __contains__(self, key: V) -> Bool
Check if a given key is in the Counter or not.
Args:
- key (
V): The key to check.
Returns:
Bool: True if there key exists in the Counter, False otherwise.
__add__
def __add__(self, other: Self) -> Self
Add counts from two Counters.
Args:
- other (
Self): The otherCounterto add to thisCounter.
Returns:
Self: A new Counter with the counts from both Counters added together.
__sub__
def __sub__(self, other: Self) -> Self
Subtract counts, but keep only results with positive counts.
Args:
- other (
Self): The otherCounterto subtract from thisCounter.
Returns:
Self: A new Counter with the counts from the other Counter subtracted
from this Counter.
__and__
def __and__(self, other: Self) -> Self
Intersection: keep common elements with the minimum count.
Args:
- other (
Self): The otherCounterto intersect with.
Returns:
Self: A new Counter with the common elements and the minimum count of
the two Counters.
__or__
def __or__(self, other: Self) -> Self
Union: keep all elements with the maximum count.
Args:
- other (
Self): The otherCounterto union with.
Returns:
Self: A new Counter with all elements and the maximum count of the two
Counters.
__iadd__
def __iadd__(mut self, other: Self)
Add counts from another Counter to this Counter.
Args:
- other (
Self): The otherCounterto add to thisCounter.
__isub__
def __isub__(mut self, other: Self)
Subtract counts from another Counter from this Counter, but keep only results with positive counts.
Args:
- other (
Self): The otherCounterto subtract from thisCounter.
__iand__
def __iand__(mut self, other: Self)
Intersection: keep common elements with the minimum count.
Args:
- other (
Self): The otherCounterto intersect with.
__ior__
def __ior__(mut self, other: Self)
Union: keep all elements with the maximum count.
Args:
- other (
Self): The otherCounterto union with.
fromkeys
static def fromkeys(keys: List[V], value: Int) -> Self
Create a new Counter from a list of keys and a default value.
Example:
from std.collections import Counter
var counter = Counter[String].fromkeys(["a", "b", "c"], 1)
print(counter["a"]) # output: 1
Args:
- keys (
List[V]): The keys to create theCounterfrom. - value (
Int): The default value to associate with each key. Must be non-negative.
Returns:
Self: A new Counter with the count of each passed key set to value.
__iter__
def __iter__(deinit self) -> Self.IteratorOwnedType
Consume the counter and iterate over its keys.
Returns:
Self.IteratorOwnedType: An iterator that owns the counter's keys.
def __iter__(ref self) -> _DictKeyIter[V, Int, H, origin_of(self)]
Iterate over the Counter's keys as immutable references.
Returns:
_DictKeyIter[V, Int, H, origin_of(self)]: An iterator of immutable references to the Counter values.
__len__
def __len__(self) -> Int
Returns the number of elements currently stored in the Counter.
Returns:
Int: The number of elements in the Counter.
write_to
def write_to(self, mut writer: T) where conforms_to(V, AnyType & Writable)
Write this Counter to a writer.
Constraints:
V must conform to Writable.
Args:
- writer (
T): The object to write to.
write_repr_to
def write_repr_to(self, mut writer: T) where conforms_to(V, AnyType & Writable)
Write the repr of this Counter to a writer.
Constraints:
V must conform to Writable.
Args:
- writer (
T): The object to write to.
le
def le(self, other: Self) -> Bool
Check if all counts are less than or equal to those in the other Counter.
Note that since we check that all counts satisfy the condition, this
comparison does not make Counters totally ordered.
Example:
from std.collections import Counter
var counter = Counter[Int]([1, 2, 1, 2, 3, 3, 3])
var other = Counter[Int].fromkeys([1, 2, 3], 10)
print(counter.le(other)) # output: True
counter[3] += 20
print(counter.le(other)) # output: False
Args:
- other (
Self): The otherCounterto compare to.
Returns:
Bool: True if all counts are less than or equal to the other Counter,
False otherwise.
lt
def lt(self, other: Self) -> Bool
Check if all counts are less than those in the other Counter.
Note that since we check that all counts satisfy the condition, this
comparison does not make Counters totally ordered.
Example:
from std.collections import Counter
var counter = Counter[Int]([1, 2, 1, 2, 3, 3])
var other = Counter[Int].fromkeys([1, 2, 3], 3)
print(counter.lt(other)) # output: True
counter[1] += 1
print(counter.lt(other)) # output: False
Args:
- other (
Self): The otherCounterto compare to.
Returns:
Bool: True if all counts are less than in the other Counter, False
otherwise.
gt
def gt(self, other: Self) -> Bool
Check if all counts are greater than those in the other Counter.
Note that since we check that all counts satisfy the condition, this
comparison does not make Counters totally ordered.
Example:
from std.collections import Counter
var counter = Counter[Int]([1, 2, 1, 2, 3, 3])
var other = Counter[Int].fromkeys([1, 2, 3], 3)
print(other.gt(counter)) # output: True
counter[1] += 1
print(other.gt(counter)) # output: False
Args:
- other (
Self): The otherCounterto compare to.
Returns:
Bool: True if all counts are greater than in the other Counter,
False otherwise.
ge
def ge(self, other: Self) -> Bool
Check if all counts are greater than or equal to those in the other Counter.
Note that since we check that all counts satisfy the condition, this
comparison does not make Counters totally ordered.
Example:
from std.collections import Counter
var counter = Counter[Int]([1, 2, 1, 2, 3, 3, 3])
var other = Counter[Int].fromkeys([1, 2, 3], 10)
print(other.ge(counter)) # output: True
counter[3] += 20
print(other.ge(counter)) # output: False
Args:
- other (
Self): The otherCounterto compare to.
Returns:
Bool: True if all counts are greater than or equal to the other
Counter, False otherwise.
get
def get(self, value: V) -> Optional[Int]
Get a value from the Counter.
Example:
from std.collections import Counter
var counter = Counter[String].fromkeys(["a", "b", "c"], 1)
print(counter.get("a").or_else(0)) # output: 1
print(counter.get("d").or_else(0)) # output: 0
Args:
- value (
V): The value to search for in theCounter.
Returns:
Optional[Int]: An optional value containing a copy of the value if it was present,
otherwise an empty Optional.
def get(self, value: V, default: Int) -> Int
Get a value from the Counter.
Example:
from std.collections import Counter
var counter = Counter[String].fromkeys(["a", "b", "c"], 1)
print(counter.get("a", default=0)) # output: 1
print(counter.get("d", default=0)) # output: 0
Args:
- value (
V): The value to search for in theCounter. - default (
Int): Default count to return.
Returns:
Int: A copy of the value if it was present, otherwise default.
pop
def pop(mut self, value: V) -> Int
Remove a value from the Counter by value.
Example:
from std.collections import Counter
var counter = Counter[String].fromkeys(["a", "b", "c"], 1)
print(counter.get("b").or_else(0)) # output: 1
try:
var count = counter.pop("b")
print(count) # output: 1
print(counter.get("b").or_else(0)) # output: 0
except e:
print(e) # KeyError if the key was not in the counter
Args:
- value (
V): The value to remove from theCounter.
Returns:
Int: The value associated with the key, if it was in the Counter.
Raises:
"KeyError" if the key was not present in the Counter.
def pop(mut self, value: V, var default: Int) -> Int
Remove a value from the Counter by value.
Example:
from std.collections import Counter
var counter = Counter[String].fromkeys(["a", "b", "c"], 1)
var count = counter.pop("b", default=100)
print(count) # output: 1
count = counter.pop("not-a-key", default=0)
print(count) # output 0
Args:
- value (
V): The value to remove from theCounter. - default (
Int): Optionally provide a default value to return if the value was not found instead of raising.
Returns:
Int: The value associated with the key, if it was in the Counter.
If it wasn't, return the provided default value instead.
keys
def keys(ref self) -> _DictKeyIter[V, Int, H, origin_of(self._data)]
Iterate over the Counter's keys as immutable references.
Example:
from std.collections import Counter
var counter = Counter[String].fromkeys(["d", "b", "a", "c"], 1)
var key_list = List[String]()
for key in counter.keys():
key_list.append(key)
sort(key_list[:])
print(key_list) # output: ['a', 'b', 'c', 'd']
Returns:
_DictKeyIter[V, Int, H, origin_of(self._data)]: An iterator of immutable references to the Counter keys.
values
def values(ref self) -> _DictValueIter[V, Int, H, origin_of(self._data)]
Iterate over the Counter's values as references.
Example:
from std.collections import Counter
# Construct `counter`
var counter = Counter[Int]([1, 2, 3, 1, 2, 1, 1, 1, 2, 5, 2, 9])
# Find most populous key
var max_count: Int = Int.MIN
for count in counter.values():
if count > max_count:
max_count = count
# Max count is the five ones
print(max_count) # output: 5
Returns:
_DictValueIter[V, Int, H, origin_of(self._data)]: An iterator of references to the Counter values.
items
def items(self) -> _DictEntryIter[V, Int, H, origin_of(self._data)]
Iterate over the Counter's entries as immutable references.
Example:
from std.collections import Counter
var counter = Counter[Int]([1, 2, 1, 2, 1, 1, 1, 2, 2])
for count in counter.items():
print(count.key, count.value)
# output: 1 5
# output: 2 4
Returns:
_DictEntryIter[V, Int, H, origin_of(self._data)]: An iterator of immutable references to the Counter entries.
clear
def clear(mut self)
Remove all elements from the Counter.
Example:
from std.collections import Counter
var counter = Counter[Int]([1, 2, 1, 2, 1, 1, 1, 2, 2])
print(counter.total()) # output: 9 (5 ones + 4 twos)
counter.clear() # Removes both entries
print(counter.total()) # output: 0
popitem
def popitem(mut self) -> CountTuple[V]
Remove and return an arbitrary (key, value) pair from the Counter. Useful for destructively iterating over the Counter. Returns in LIFO order.
Example:
from std.collections import Counter
var counter = Counter[String].fromkeys(["a", "b", "c"], 5)
try:
var tuple = counter.popitem()
print(tuple._value, tuple._count)
# output: probably c 5 since that was last in
except e:
print(e) # KeyError if the key was not in the counter
Returns:
CountTuple[V]: A CountTuple containing the key and value of the removed item.
Raises:
"KeyError" if the Counter is empty.
total
def total(self) -> UInt
Return the total of all counts in the Counter.
Example:
from std.collections import Counter
var counter = Counter[Int]([1, 2, 1, 2, 1, 1, 1, 2, 2])
print(counter.total()) # output: 9 (5 ones + 4 twos)
counter.clear() # Removes both entries
print(counter.total()) # output: 0
Returns:
UInt: The total of all counts in the Counter.
most_common
def most_common(self, n: UInt) -> List[CountTuple[V]]
Return a list of the n most common elements and their counts from the most common to the least.
Example:
from std.collections import Counter
var counter = Counter[Int]([1, 2, 1, 2, 3, 3, 3, 1, 1, 1, 6, 6, 2, 2, 7])
for tuple in counter.most_common(2):
print(tuple._value, tuple._count)
# output: 1 5
# output: 2 4
Args:
- n (
UInt): The number of most common elements to return.
Returns:
List[CountTuple[V]]: A list of the n most common elements and their counts.
elements
def elements(self) -> List[V]
Return an iterator over elements repeating each as many times as its count.
Example:
from std.collections import Counter
var counter = Counter[Int]([1, 2, 1, 2, 3, 3, 3, 1, 1, 1, 6, 6, 2, 2, 7])
print(counter.elements())
# output: [1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 6, 6, 7]
Returns:
List[V]: An iterator over the elements in the Counter.
update
def update(mut self, other: Self)
Update the Counter, like Dict.update() but add counts instead of replacing them.
Example:
from std.collections import Counter
var counter = Counter[Int]([1, 2, 1, 2, 3, 3, 3])
var other = Counter[Int].fromkeys([1, 2, 3], 10)
print(counter[1]) # output: 2
counter.update(other)
print(counter[1]) # output: 12
Args:
- other (
Self): TheCounterto update thisCounterwith.
subtract
def subtract(mut self, other: Self)
Subtract counts. Both inputs and outputs may be zero or negative.
Example:
from std.collections import Counter
var counter = Counter[Int]([1, 2, 1, 2, 3, 3, 3])
var other = Counter[Int].fromkeys([1, 2, 3], 10)
print(counter[1]) # output: 2
counter.subtract(other)
print(counter[1]) # output: -8
Args:
- other (
Self): TheCounterto subtract from thisCounter.