LinkedList
Summary
- Package:
- Doc-string:
documented
File |
Expected |
Covered |
Uncovered |
Coverage |
|---|---|---|---|---|
__init__.py |
56 |
54 |
2 |
96.4% |
Overall (1 files) |
56 |
54 |
2 |
96.4% |
Source
pyTooling/LinkedList/__init__.pydocumentedundocumentedignoredexcludednot counted
31"""
32An object-oriented doubly linked-list data structure for Python.
33
34.. seealso::
35
36 :mod:`pyTooling.Tree`
37 |rarr| A tree data structure.
38 :mod:`pyTooling.Graph`
39 |rarr| A graph data structure.
40"""
...
51
53_NodeKey = TypeVar("_NodeKey")
54_NodeValue = TypeVar("_NodeValue")
55
57@export
58class LinkedListError(ToolingException):
59 """Base-exception of all exceptions raised by :mod:`pyTooling.LinkedList`."""
60
62@export
63class InternalError(LinkedListError):
64 """
65 The exception is raised when the linked list's internal state became inconsistent.
66
67 The exception message states the discovered inconsistency. Please create a
68 :gh:`bug report <pyTooling/pyTooling/issues>` if this exception is raised.
69 """
70
72@export
73class NotInAListError(LinkedListError):
74 """The exception is raised when a node is not assigned to any linked list."""
75
76 _unlinkedNode: Node #: Node that isn't part of a linked list.
77
78 def __init__(self, message: str, /, *, unlinkedNode: Node) -> None:
79 """
80 Initializes the exception with the node that isn't part of a linked list.
81
82 :param message: The exception's message.
83 :param unlinkedNode: The node that isn't part of a linked list.
84 """
...
87
88 @readonly
89 def UnlinkedNode(self) -> Node:
90 """
91 Read-only property to access the node that isn't part of a linked list (:attr:`_unlinkedNode`).
92
93 :returns: The node.
94 """
...
96
98@export
99class NotInSameListError(LinkedListError, NotInSameHierarchyError):
100 """The exception is raised when a node is assigned to a different linked list than expected."""
101
103@export
104class EmptyListError(LinkedListError):
105 """The exception is raised when an operation needs at least one element, but the linked list is empty."""
106
108@export
109class NodeNotFoundError(LinkedListError):
110 """The exception is raised when no node matching the search criterion was found."""
111
113@export
114class Node(Generic[_NodeKey, _NodeValue], metaclass=ExtendedType, slots=True):
115 """
116 The node in an object-oriented doubly linked-list.
117
118 It contains a reference to the doubly linked list (:attr:`_list`), the previous node (:attr:`_previous`), the next
119 node (:attr:`_next`) and the data (:attr:`_value`). Optionally, a key (:attr:`_key`) can be stored for sorting
120 purposes.
121
122 The :attr:`_previous` field of the **first node** in a doubly linked list is ``None``. Similarly, the :attr:`_next`
123 field of the **last node** is ``None``. ``None`` represents the end of the linked list when iterating it node-by-node.
124 """
125
126 _linkedList: Nullable[LinkedList[_NodeKey, _NodeValue]] #: Reference to the doubly linked list instance.
127 _previousNode: Nullable[Node[_NodeKey, _NodeValue]] #: Reference to the previous node.
128 _nextNode: Nullable[Node[_NodeKey, _NodeValue]] #: Reference to the next node.
129 _key: Nullable[_NodeKey] #: The sortable key of the node.
130 _value: _NodeValue #: The value of the node.
131
132 def __init__(
133 self,
134 value: _NodeValue,
135 key: Nullable[_NodeKey] = None,
136 previousNode: Nullable[Node[_NodeKey, _NodeValue]] = None,
137 nextNode: Nullable[Node[_NodeKey, _NodeValue]] = None
138 ) -> None:
139 """
140 Initialize a linked list node.
141
142 :param value: Value to store in the node.
143 :param key: Optional, sortable key to store in the node.
144 :param previousNode: Optional, reference to the previous node.
145 :param nextNode: Optional, reference to the next node.
146 :raises TypeError: If parameter 'previous' is not of type :class:`Node`.
147 :raises TypeError: If parameter 'next' is not of type :class:`Node`.
148 :raises ValueError: If parameter 'value' is None.
149 :raises ValueError: If ``previous`` and ``next`` belong to different linked lists. |br|
150 A node can only be inserted between two neighbours of the same linked list.
151 """
...
219
220 @readonly
221 def List(self) -> Nullable[LinkedList[_NodeKey, _NodeValue]]:
222 """
223 Read-only property to access the linked list, this node belongs to.
224
225 :returns: The linked list, this node is part of, or ``None``.
226 """
...
228
229 @readonly
230 def PreviousNode(self) -> Nullable[Node[_NodeKey, _NodeValue]]:
231 """
232 Read-only property to access node's predecessor.
233
234 This reference is ``None`` if the node is the first node in the doubly linked list.
235
236 :returns: The node before the current node or ``None``.
237 """
...
239
240 @readonly
241 def NextNode(self) -> Nullable[Node[_NodeKey, _NodeValue]]:
242 """
243 Read-only property to access node's successor.
244
245 This reference is ``None`` if the node is the last node in the doubly linked list.
246
247 :returns: The node after the current node or ``None``.
248 """
...
250
251 @property
252 def Key(self) -> _NodeKey:
253 """
254 Property to access the node's internal key.
255
256 The key can be a scalar or a reference to an object.
257
258 :returns: The node's key.
259 """
...
261
262 @Key.setter
263 def Key(self, key: _NodeKey) -> None:
...
265
266 @property
267 def Value(self) -> _NodeValue:
268 """
269 Property to access the node's internal data.
270
271 The data can be a scalar or a reference to an object.
272
273 :returns: The node's value.
274 """
...
276
277 @Value.setter
278 def Value(self, value: _NodeValue) -> None:
...
280
281 def InsertNodeBefore(self, node: Node[_NodeKey, _NodeValue]) -> None:
282 """
283 Insert a node before this node.
284
285 :param node: Node to insert.
286 :raises ValueError: If parameter 'node' is ``None``.
287 :raises TypeError: If parameter 'node' is not of type :class:`Node`.
288 :raises NotInSameListError: If parameter 'node' is already part of another linked list.
289 :raises NotInAListError: If this node is not part of a linked list.
290 """
...
314
315 def InsertNodeAfter(self, node: Node[_NodeKey, _NodeValue]) -> None:
316 """
317 Insert a node after this node.
318
319 :param node: Node to insert.
320 :raises ValueError: If parameter 'node' is ``None``.
321 :raises TypeError: If parameter 'node' is not of type :class:`Node`.
322 :raises NotInSameListError: If parameter 'node' is already part of another linked list.
323 :raises NotInAListError: If this node is not part of a linked list.
324 """
...
348
367 def Remove(self) -> _NodeValue:
368 """
369 Remove this node from the linked list.
370
371 :returns: The value of the removed node.
372 """
...
406
407 def IterateToFirst(self, includeSelf: bool = False) -> Generator[Node[_NodeKey, _NodeValue], None, None]:
408 """
409 Return a generator iterating backward from this node to the list's first node.
410
411 Optionally, this node can be included into the generated sequence.
412
413 :param includeSelf: Optional, if ``True``, include this node into the sequence, otherwise start at previous node.
414 :returns: A sequence of nodes towards the list's first node.
415 """
...
426
427 def IterateToLast(self, includeSelf: bool = False) -> Generator[Node[_NodeKey, _NodeValue], None, None]:
428 """
429 Return a generator iterating forward from this node to the list's last node.
430
431 Optionally, this node can be included into the generated sequence by setting.
432
433 :param includeSelf: Optional, if ``True``, include this node into the sequence, otherwise start at next node.
434 :returns: A sequence of nodes towards the list's last node.
435 """
...
446
447 def __repr__(self) -> str:
448 """
449 Return a detailed string representation of this node.
450
451 :returns: The node's value, prefixed by its kind.
452 """
...
454
456@export
457class LinkedList(Generic[_NodeKey, _NodeValue], metaclass=ExtendedType, slots=True):
458 """An object-oriented doubly linked-list."""
459
460 _firstNode: Nullable[Node[_NodeKey, _NodeValue]] #: Reference to the first node of the linked list.
461 _lastNode: Nullable[Node[_NodeKey, _NodeValue]] #: Reference to the last node of the linked list.
462 _count: int #: Number of nodes in the linked list.
463
465 def __init__(self, nodes: Nullable[Iterable[Node[_NodeKey, _NodeValue]]] = None) -> None:
466 """
467 Initialize an empty linked list.
468
469 Optionally, an iterable can be given to initialize the linked list. The order is preserved.
470
471 :param nodes: Optional, iterable to initialize the linked list.
472 :raises TypeError: If parameter 'nodes' is not an :class:`iterable <typing.Iterable>`.
473 :raises TypeError: If parameter 'nodes' items are not of type :class:`Node`.
474 :raises NotInSameListError: If parameter 'nodes' contains items which are already part of another linked list.
475 """
...
529
530 @readonly
531 def IsEmpty(self) -> int:
532 """
533 Read-only property to return the number of .
534
535 This reference is ``None`` if the node is the last node in the doubly linked list.
536
537 :returns: ``True`` if linked list is empty, otherwise ``False``
538 """
...
540
541 @readonly
542 def Count(self) -> int:
543 """
544 Read-only property to access the number of nodes in the linked list.
545
546 :returns: Number of nodes.
547 """
...
549
550 @readonly
551 def FirstNode(self) -> Nullable[Node[_NodeKey, _NodeValue]]:
552 """
553 Read-only property to access the first node in the linked list.
554
555 In case the list is empty, ``None`` is returned.
556
557 :returns: First node.
558 """
...
560
561 @readonly
562 def LastNode(self) -> Nullable[Node[_NodeKey, _NodeValue]]:
563 """
564 Read-only property to access the last node in the linked list.
565
566 In case the list is empty, ``None`` is returned.
567
568 :returns: Last node.
569 """
...
571
572 def Clear(self) -> None:
573 """
574 Clear the linked list.
575
576 Every node is removed: afterwards, it belongs to no linked list and has neither a previous nor a next node, so it
577 can be inserted into a linked list again.
578 """
...
590
591 def InsertBeforeFirst(self, node: Node[_NodeKey, _NodeValue]) -> None:
592 """
593 Insert a node before the first node.
594
595 :param node: Node to insert.
596 :raises ValueError: If parameter 'node' is ``None``.
597 :raises TypeError: If parameter 'node' is not of type :class:`Node`.
598 :raises NotInSameListError: If parameter 'node' is already part of another linked list.
599 """
...
620
621 def InsertAfterLast(self, node: Node[_NodeKey, _NodeValue]) -> None:
622 """
623 Insert a node after the last node.
624
625 :param node: Node to insert.
626 :raises ValueError: If parameter 'node' is ``None``.
627 :raises TypeError: If parameter 'node' is not of type :class:`Node`.
628 :raises NotInSameListError: If parameter 'node' is already part of another linked list.
629 """
...
650
651 def RemoveFirst(self) -> Node[_NodeKey, _NodeValue]:
652 """
653 Remove first node from linked list.
654
655 :returns: First node.
656 :raises EmptyListError: If linked list is empty.
657 """
...
673
674 def RemoveLast(self) -> Node[_NodeKey, _NodeValue]:
675 """
676 Remove last node from linked list.
677
678 :returns: Last node.
679 :raises EmptyListError: If linked list is empty.
680 """
...
696
698 def GetNodeByIndex(self, index: int) -> Node[_NodeKey, _NodeValue]:
699 """
700 Access a node in the linked list by position.
701
702 :param index: Node position to access.
703 :returns: Node at the given position.
704 :raises ValueError: If parameter 'position' is out of range, which includes an empty list.
705 :raises InternalError: If the node at that position could not be reached, so the list's internal state is
706 inconsistent.
707
708 .. note::
709
710 The algorithm starts iterating nodes from the shorter end.
711 """
...
748
749 def Search(self, predicate: Predicate[Node], reverse: bool = False) -> Node[_NodeKey, _NodeValue]:
750 """
751 Search the list for the first node matching a predicate.
752
753 :param predicate: Filter function accepting a node and returning a boolean.
754 :param reverse: Optional, if ``True``, search from the last node towards the first.
755 :returns: The first matching node.
756 :raises EmptyListError: If the list is empty.
757 :raises NodeNotFoundError: If no node matches the predicate.
758 """
...
782
783 def Reverse(self) -> None:
784 """
785 Reverse the order of nodes in the linked list.
786 """
...
799
800 def Sort(self, key: Nullable[Callable[[Node[_NodeKey, _NodeValue]], Any]] = None, reverse: bool = False) -> None:
801 """
802 Sort the linked list in ascending or descending order.
803
804 The sort operation is **stable**.
805
806 :param key: Optional, function to access a user-defined key for sorting.
807 :param reverse: Optional, parameter, if ``True`` sort in descending order, otherwise in ascending order.
808
809 .. note::
810
811 The linked list is converted to an array, which is sorted by quicksort using the builtin :meth:`~list.sort`.
812 Afterward, the sorted array is used to reconstruct the linked list in requested order.
813 """
...
839
840 def IterateFromFirst(self) -> Generator[Node[_NodeKey, _NodeValue], None, None]:
841 """
842 Return a generator iterating forward from list's first node to list's last node.
843
844 :returns: A sequence of nodes towards the list's last node.
845 """
...
854
855 def IterateFromLast(self) -> Generator[Node[_NodeKey, _NodeValue], None, None]:
856 """
857 Return a generator iterating backward from list's last node to list's first node.
858
859 :returns: A sequence of nodes towards the list's first node.
860 """
...
869
870 def ToList(self, reverse: bool = False) -> list[Node[_NodeKey, _NodeValue]]:
871 """
872 Convert the linked list to a :class:`list`.
873
874 Optionally, the resulting list can be constructed in reverse order.
875
876 :param reverse: Optional, parameter, if ``True`` return in reversed order, otherwise in normal order.
877 :returns: A list (array) of this linked list's values.
878 """
...
885
886 def ToTuple(self, reverse: bool = False) -> tuple[Node[_NodeKey, _NodeValue], ...]:
887 """
888 Convert the linked list to a :class:`tuple`.
889
890 Optionally, the resulting tuple can be constructed in reverse order.
891
892 :param reverse: Optional, parameter, if ``True`` return in reversed order, otherwise in normal order.
893 :returns: A tuple of this linked list's values.
894 """
...
901
931 def __len__(self) -> int:
932 """
933 Returns the number of nodes in the linked list.
934
935 :returns: Number of nodes.
936 """
...
938
939 def __getitem__(self, index: int) -> _NodeValue:
940 """
941 Access a node's value by its index.
942
943 :param index: Node index to access.
944 :returns: Node's value at the given index.
945 :raises ValueError: If parameter 'index' is out of range.
946
947 .. note::
948
949 The algorithm starts iterating nodes from the shorter end.
950 """
...
952
953 def __setitem__(self, index: int, value: _NodeValue) -> None:
954 """
955 Set the value of node at the given position.
956
957 :param index: Index of the node to modify.
958 :param value: New value for the node's value addressed by index.
959 """
...
961
962 def __delitem__(self, index: int) -> Node[_NodeKey, _NodeValue]:
963 """
964 Remove a node at the given index.
965
966 :param index: Index of the node to remove.
967 :returns: Removed node.
968 """
...