LinkedList

Summary

Package:

pyTooling

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		"""
		...