Rework multiset methods to use less memory and to make fewer calls to __hash__.
This commit is contained in:
commit
c15d9e759f
|
@ -572,10 +572,13 @@ class Counter(dict):
|
||||||
if not isinstance(other, Counter):
|
if not isinstance(other, Counter):
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
result = Counter()
|
result = Counter()
|
||||||
for elem in set(self) | set(other):
|
for elem, count in self.items():
|
||||||
newcount = self[elem] + other[elem]
|
newcount = count + other[elem]
|
||||||
if newcount > 0:
|
if newcount > 0:
|
||||||
result[elem] = newcount
|
result[elem] = newcount
|
||||||
|
for elem, count in other.items():
|
||||||
|
if elem not in self and count > 0:
|
||||||
|
result[elem] = count
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def __sub__(self, other):
|
def __sub__(self, other):
|
||||||
|
@ -588,10 +591,13 @@ class Counter(dict):
|
||||||
if not isinstance(other, Counter):
|
if not isinstance(other, Counter):
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
result = Counter()
|
result = Counter()
|
||||||
for elem in set(self) | set(other):
|
for elem, count in self.items():
|
||||||
newcount = self[elem] - other[elem]
|
newcount = count - other[elem]
|
||||||
if newcount > 0:
|
if newcount > 0:
|
||||||
result[elem] = newcount
|
result[elem] = newcount
|
||||||
|
for elem, count in other.items():
|
||||||
|
if elem not in self and count < 0:
|
||||||
|
result[elem] = 0 - count
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def __or__(self, other):
|
def __or__(self, other):
|
||||||
|
@ -604,11 +610,14 @@ class Counter(dict):
|
||||||
if not isinstance(other, Counter):
|
if not isinstance(other, Counter):
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
result = Counter()
|
result = Counter()
|
||||||
for elem in set(self) | set(other):
|
for elem, count in self.items():
|
||||||
p, q = self[elem], other[elem]
|
other_count = other[elem]
|
||||||
newcount = q if p < q else p
|
newcount = other_count if count < other_count else count
|
||||||
if newcount > 0:
|
if newcount > 0:
|
||||||
result[elem] = newcount
|
result[elem] = newcount
|
||||||
|
for elem, count in other.items():
|
||||||
|
if elem not in self and count > 0:
|
||||||
|
result[elem] = count
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def __and__(self, other):
|
def __and__(self, other):
|
||||||
|
@ -621,11 +630,9 @@ class Counter(dict):
|
||||||
if not isinstance(other, Counter):
|
if not isinstance(other, Counter):
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
result = Counter()
|
result = Counter()
|
||||||
if len(self) < len(other):
|
for elem, count in self.items():
|
||||||
self, other = other, self
|
other_count = other[elem]
|
||||||
for elem in filter(self.__contains__, other):
|
newcount = count if count < other_count else other_count
|
||||||
p, q = self[elem], other[elem]
|
|
||||||
newcount = p if p < q else q
|
|
||||||
if newcount > 0:
|
if newcount > 0:
|
||||||
result[elem] = newcount
|
result[elem] = newcount
|
||||||
return result
|
return result
|
||||||
|
|
Loading…
Reference in New Issue