Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
227
venv/Lib/site-packages/pyrsistent/_pset.py
Normal file
227
venv/Lib/site-packages/pyrsistent/_pset.py
Normal file
|
@ -0,0 +1,227 @@
|
|||
from collections.abc import Set, Hashable
|
||||
import sys
|
||||
from pyrsistent._pmap import pmap
|
||||
|
||||
|
||||
class PSet(object):
|
||||
"""
|
||||
Persistent set implementation. Built on top of the persistent map. The set supports all operations
|
||||
in the Set protocol and is Hashable.
|
||||
|
||||
Do not instantiate directly, instead use the factory functions :py:func:`s` or :py:func:`pset`
|
||||
to create an instance.
|
||||
|
||||
Random access and insert is log32(n) where n is the size of the set.
|
||||
|
||||
Some examples:
|
||||
|
||||
>>> s = pset([1, 2, 3, 1])
|
||||
>>> s2 = s.add(4)
|
||||
>>> s3 = s2.remove(2)
|
||||
>>> s
|
||||
pset([1, 2, 3])
|
||||
>>> s2
|
||||
pset([1, 2, 3, 4])
|
||||
>>> s3
|
||||
pset([1, 3, 4])
|
||||
"""
|
||||
__slots__ = ('_map', '__weakref__')
|
||||
|
||||
def __new__(cls, m):
|
||||
self = super(PSet, cls).__new__(cls)
|
||||
self._map = m
|
||||
return self
|
||||
|
||||
def __contains__(self, element):
|
||||
return element in self._map
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self._map)
|
||||
|
||||
def __len__(self):
|
||||
return len(self._map)
|
||||
|
||||
def __repr__(self):
|
||||
if not self:
|
||||
return 'p' + str(set(self))
|
||||
|
||||
return 'pset([{0}])'.format(str(set(self))[1:-1])
|
||||
|
||||
def __str__(self):
|
||||
return self.__repr__()
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self._map)
|
||||
|
||||
def __reduce__(self):
|
||||
# Pickling support
|
||||
return pset, (list(self),)
|
||||
|
||||
@classmethod
|
||||
def _from_iterable(cls, it, pre_size=8):
|
||||
return PSet(pmap(dict((k, True) for k in it), pre_size=pre_size))
|
||||
|
||||
def add(self, element):
|
||||
"""
|
||||
Return a new PSet with element added
|
||||
|
||||
>>> s1 = s(1, 2)
|
||||
>>> s1.add(3)
|
||||
pset([1, 2, 3])
|
||||
"""
|
||||
return self.evolver().add(element).persistent()
|
||||
|
||||
def update(self, iterable):
|
||||
"""
|
||||
Return a new PSet with elements in iterable added
|
||||
|
||||
>>> s1 = s(1, 2)
|
||||
>>> s1.update([3, 4, 4])
|
||||
pset([1, 2, 3, 4])
|
||||
"""
|
||||
e = self.evolver()
|
||||
for element in iterable:
|
||||
e.add(element)
|
||||
|
||||
return e.persistent()
|
||||
|
||||
def remove(self, element):
|
||||
"""
|
||||
Return a new PSet with element removed. Raises KeyError if element is not present.
|
||||
|
||||
>>> s1 = s(1, 2)
|
||||
>>> s1.remove(2)
|
||||
pset([1])
|
||||
"""
|
||||
if element in self._map:
|
||||
return self.evolver().remove(element).persistent()
|
||||
|
||||
raise KeyError("Element '%s' not present in PSet" % element)
|
||||
|
||||
def discard(self, element):
|
||||
"""
|
||||
Return a new PSet with element removed. Returns itself if element is not present.
|
||||
"""
|
||||
if element in self._map:
|
||||
return self.evolver().remove(element).persistent()
|
||||
|
||||
return self
|
||||
|
||||
class _Evolver(object):
|
||||
__slots__ = ('_original_pset', '_pmap_evolver')
|
||||
|
||||
def __init__(self, original_pset):
|
||||
self._original_pset = original_pset
|
||||
self._pmap_evolver = original_pset._map.evolver()
|
||||
|
||||
def add(self, element):
|
||||
self._pmap_evolver[element] = True
|
||||
return self
|
||||
|
||||
def remove(self, element):
|
||||
del self._pmap_evolver[element]
|
||||
return self
|
||||
|
||||
def is_dirty(self):
|
||||
return self._pmap_evolver.is_dirty()
|
||||
|
||||
def persistent(self):
|
||||
if not self.is_dirty():
|
||||
return self._original_pset
|
||||
|
||||
return PSet(self._pmap_evolver.persistent())
|
||||
|
||||
def __len__(self):
|
||||
return len(self._pmap_evolver)
|
||||
|
||||
def copy(self):
|
||||
return self
|
||||
|
||||
def evolver(self):
|
||||
"""
|
||||
Create a new evolver for this pset. For a discussion on evolvers in general see the
|
||||
documentation for the pvector evolver.
|
||||
|
||||
Create the evolver and perform various mutating updates to it:
|
||||
|
||||
>>> s1 = s(1, 2, 3)
|
||||
>>> e = s1.evolver()
|
||||
>>> _ = e.add(4)
|
||||
>>> len(e)
|
||||
4
|
||||
>>> _ = e.remove(1)
|
||||
|
||||
The underlying pset remains the same:
|
||||
|
||||
>>> s1
|
||||
pset([1, 2, 3])
|
||||
|
||||
The changes are kept in the evolver. An updated pmap can be created using the
|
||||
persistent() function on the evolver.
|
||||
|
||||
>>> s2 = e.persistent()
|
||||
>>> s2
|
||||
pset([2, 3, 4])
|
||||
|
||||
The new pset will share data with the original pset in the same way that would have
|
||||
been done if only using operations on the pset.
|
||||
"""
|
||||
return PSet._Evolver(self)
|
||||
|
||||
# All the operations and comparisons you would expect on a set.
|
||||
#
|
||||
# This is not very beautiful. If we avoid inheriting from PSet we can use the
|
||||
# __slots__ concepts (which requires a new style class) and hopefully save some memory.
|
||||
__le__ = Set.__le__
|
||||
__lt__ = Set.__lt__
|
||||
__gt__ = Set.__gt__
|
||||
__ge__ = Set.__ge__
|
||||
__eq__ = Set.__eq__
|
||||
__ne__ = Set.__ne__
|
||||
|
||||
__and__ = Set.__and__
|
||||
__or__ = Set.__or__
|
||||
__sub__ = Set.__sub__
|
||||
__xor__ = Set.__xor__
|
||||
|
||||
issubset = __le__
|
||||
issuperset = __ge__
|
||||
union = __or__
|
||||
intersection = __and__
|
||||
difference = __sub__
|
||||
symmetric_difference = __xor__
|
||||
|
||||
isdisjoint = Set.isdisjoint
|
||||
|
||||
Set.register(PSet)
|
||||
Hashable.register(PSet)
|
||||
|
||||
_EMPTY_PSET = PSet(pmap())
|
||||
|
||||
|
||||
def pset(iterable=(), pre_size=8):
|
||||
"""
|
||||
Creates a persistent set from iterable. Optionally takes a sizing parameter equivalent to that
|
||||
used for :py:func:`pmap`.
|
||||
|
||||
>>> s1 = pset([1, 2, 3, 2])
|
||||
>>> s1
|
||||
pset([1, 2, 3])
|
||||
"""
|
||||
if not iterable:
|
||||
return _EMPTY_PSET
|
||||
|
||||
return PSet._from_iterable(iterable, pre_size=pre_size)
|
||||
|
||||
|
||||
def s(*elements):
|
||||
"""
|
||||
Create a persistent set.
|
||||
|
||||
Takes an arbitrary number of arguments to insert into the new set.
|
||||
|
||||
>>> s1 = s(1, 2, 3, 2)
|
||||
>>> s1
|
||||
pset([1, 2, 3])
|
||||
"""
|
||||
return pset(elements)
|
Loading…
Add table
Add a link
Reference in a new issue