partition#

Partition module.

A partition is a division of a set into non-empty, disjoint subsets (parts). Partitions are used to represent splits and other set-theoretic structures in phylogenetic analysis. This module provides the Partition class for working with partitions of sets.

class phylozoo.core.primitives.partition.Partition(parts: list[set[T]])[source]#

Bases: object

General class for partitions of sets.

A partition is a collection of disjoint sets (called parts or blocks) whose union equals the original set. Each element appears in exactly one part.

This class is immutable - once created, the partition structure cannot be modified. All parts are stored as frozensets.

Parameters:

parts (list[set[T]]) – List of sets of elements. The sets must be disjoint (no overlapping elements).

Raises:

Notes

The partition is immutable after initialization. Attempts to modify attributes will raise AttributeError.

Examples

>>> partition = Partition([{1, 2}, {3, 4}, {5}])
>>> len(partition)
3
>>> partition.size()
5
>>> {1, 2} in partition
True
>>> partition.get_part(3)
frozenset({3, 4})
>>> partition.parts  # Read-only tuple
(frozenset({1, 2}), frozenset({3, 4}), frozenset({5}))
__contains__(subset: set[T, frozenset]) bool[source]#

Check if a subset is one of the parts in the partition.

Parameters:

subset (set[T, frozenset]) – Subset to check.

Returns:

True if the subset is a part of the partition, False otherwise.

Return type:

bool

Examples

>>> partition = Partition([{1, 2}, {3, 4}])
>>> {1, 2} in partition
True
>>> {1, 3} in partition
False
__eq__(other: Any) bool[source]#

Check if two partitions are equal.

Two partitions are equal if they have the same parts (order doesn’t matter). Since parts are stored in canonical (sorted) order, we can compare tuples directly.

Parameters:

other (Any) – Object to compare with.

Returns:

True if partitions are equal, False otherwise.

Return type:

bool

Examples

>>> p1 = Partition([{1, 2}, {3, 4}])
>>> p2 = Partition([{3, 4}, {1, 2}])
>>> p1 == p2
True
__hash__() int[source]#

Return hash of the partition.

Returns:

Hash value based on the parts.

Return type:

int

Notes

Partitions are hashable because parts are stored as frozensets. Since parts are stored in canonical (sorted) order, we can hash the tuple directly.

__iter__() Iterator[frozenset][source]#

Return an iterator over the parts of the partition.

The iteration order is deterministic and consistent regardless of the input order. Parts are sorted by size first, then by their elements in sorted order.

Returns:

Iterator over the parts in sorted order.

Return type:

Iterator[frozenset]

Examples

>>> partition = Partition([{3, 4}, {1, 2}])
>>> list(partition)
[frozenset({1, 2}), frozenset({3, 4})]  # Always sorted, regardless of input order
__len__() int[source]#

Return the number of parts in the partition.

Returns:

Number of parts (blocks) in the partition.

Return type:

int

Examples

>>> partition = Partition([{1, 2}, {3, 4}, {5}])
>>> len(partition)
3
__repr__() str[source]#

Return string representation of the partition.

Returns:

String representation showing the parts as sets.

Return type:

str

__setattr__(name: str, value: Any) None[source]#

Prevent modification of attributes after initialization.

Raises:

PhyloZooAttributeError – If attempting to modify any attribute after initialization.

property elements: frozenset#

Get the elements of the partition (read-only).

Returns:

Frozen set containing all elements in the partition.

Return type:

frozenset

get_part(element: T) frozenset[source]#

Get the part that contains the given element.

Parameters:

element (T) – Element to find.

Returns:

The part (frozenset) containing the element.

Return type:

frozenset

Raises:

PhyloZooValueError – If the element is not found in any part of the partition.

Examples

>>> partition = Partition([{1, 2}, {3, 4}])
>>> partition.get_part(1)
frozenset({1, 2})
>>> partition.get_part(5)
ValueError: Element 5 not found in partition
is_refinement(other: Partition) bool[source]#

Check if this partition is a refinement of another partition.

A partition P is a refinement of partition Q if every part of P is a subset of some part of Q.

Parameters:

other (Partition) – The partition to check against.

Returns:

True if this partition is a refinement of ‘other’, False otherwise.

Return type:

bool

Raises:

Examples

>>> p1 = Partition([{1}, {2}, {3}])  # Fine partition
>>> p2 = Partition([{1, 2}, {3}])    # Coarser partition
>>> p1.is_refinement(p2)
True
>>> p2.is_refinement(p1)
False
property parts: tuple#

Get the parts of the partition (read-only).

Returns:

Tuple of frozensets representing the partition blocks.

Return type:

tuple

representative_partitions() Iterator[Partition][source]#

Generate all partitions with exactly one element per part.

For each part in the current partition, selects exactly one element, creating a new partition where each part is a singleton set.

Yields:

Partition – Representative partitions with exactly one element per part.

Examples

>>> partition = Partition([{1, 2}, {3, 4}])
>>> reps = list(partition.representative_partitions())
>>> len(reps)
4  # 2 choices from first part * 2 choices from second part
>>> reps[0]
Partition([{1}, {3}])
size() int[source]#

Return the total number of elements the partition covers.

Returns:

Total number of elements in all parts.

Return type:

int

Examples

>>> partition = Partition([{1, 2}, {3, 4}, {5}])
>>> partition.size()
5
subpartitions(size: int = 4) Iterator[Partition][source]#

Generate all subpartitions of a specified size.

A subpartition is a partition formed by selecting a subset of the parts from the current partition.

Parameters:

size (int, optional) – Number of parts to include in each subpartition, by default 4.

Yields:

Partition – Subpartitions of the specified size.

Examples

>>> partition = Partition([{1}, {2}, {3}, {4}, {5}])
>>> subparts = list(partition.subpartitions(size=2))
>>> len(subparts)
10  # C(5,2) = 10