Skip to content

Commit 66fa07f

Browse files
committed
Simplify the grouper implementation.
Mostly stylistic, except for the implementation of `__iter__` which is made much shorter: to get list of unique lists that appear in self._mapping.values(), it is simpler to construct a dict keying these lists based on their id()s rather than appending a marker on the lists and then popping the markers at the end.
1 parent acae06d commit 66fa07f

File tree

1 file changed

+14
-44
lines changed

1 file changed

+14
-44
lines changed

lib/matplotlib/cbook/__init__.py

Lines changed: 14 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -979,17 +979,13 @@ class Grouper(object):
979979
980980
"""
981981
def __init__(self, init=()):
982-
mapping = self._mapping = {}
983-
for x in init:
984-
mapping[ref(x)] = [ref(x)]
982+
self._mapping = {ref(x): [ref(x)] for x in init}
985983

986984
def __contains__(self, item):
987985
return ref(item) in self._mapping
988986

989987
def clean(self):
990-
"""
991-
Clean dead weak references from the dictionary
992-
"""
988+
"""Clean dead weak references from the dictionary."""
993989
mapping = self._mapping
994990
to_drop = [key for key in mapping if key() is None]
995991
for key in to_drop:
@@ -998,18 +994,14 @@ def clean(self):
998994

999995
def join(self, a, *args):
1000996
"""
1001-
Join given arguments into the same set. Accepts one or more
1002-
arguments.
997+
Join given arguments into the same set. Accepts one or more arguments.
1003998
"""
1004999
mapping = self._mapping
10051000
set_a = mapping.setdefault(ref(a), [ref(a)])
10061001

10071002
for arg in args:
1008-
set_b = mapping.get(ref(arg))
1009-
if set_b is None:
1010-
set_a.append(ref(arg))
1011-
mapping[ref(arg)] = set_a
1012-
elif set_b is not set_a:
1003+
set_b = mapping.get(ref(arg), [ref(arg)])
1004+
if set_b is not set_a:
10131005
if len(set_b) > len(set_a):
10141006
set_a, set_b = set_b, set_a
10151007
set_a.extend(set_b)
@@ -1019,24 +1011,15 @@ def join(self, a, *args):
10191011
self.clean()
10201012

10211013
def joined(self, a, b):
1022-
"""
1023-
Returns True if *a* and *b* are members of the same set.
1024-
"""
1014+
"""Returns True if *a* and *b* are members of the same set."""
10251015
self.clean()
1026-
1027-
mapping = self._mapping
1028-
try:
1029-
return mapping[ref(a)] is mapping[ref(b)]
1030-
except KeyError:
1031-
return False
1016+
return self._mapping.get(ref(a), object()) is self._mapping.get(ref(b))
10321017

10331018
def remove(self, a):
10341019
self.clean()
1035-
1036-
mapping = self._mapping
1037-
seta = mapping.pop(ref(a), None)
1038-
if seta is not None:
1039-
seta.remove(ref(a))
1020+
set_a = self._mapping.pop(ref(a), None)
1021+
if set_a:
1022+
set_a.remove(ref(a))
10401023

10411024
def __iter__(self):
10421025
"""
@@ -1045,26 +1028,13 @@ def __iter__(self):
10451028
The iterator is invalid if interleaved with calls to join().
10461029
"""
10471030
self.clean()
1048-
token = object()
1049-
1050-
# Mark each group as we come across if by appending a token,
1051-
# and don't yield it twice
1052-
for group in self._mapping.values():
1053-
if group[-1] is not token:
1054-
yield [x() for x in group]
1055-
group.append(token)
1056-
1057-
# Cleanup the tokens
1058-
for group in self._mapping.values():
1059-
if group[-1] is token:
1060-
del group[-1]
1031+
unique_groups = {id(group): group for group in self._mapping.values()}
1032+
for group in unique_groups.values():
1033+
yield [x() for x in group]
10611034

10621035
def get_siblings(self, a):
1063-
"""
1064-
Returns all of the items joined with *a*, including itself.
1065-
"""
1036+
"""Returns all of the items joined with *a*, including itself."""
10661037
self.clean()
1067-
10681038
siblings = self._mapping.get(ref(a), [ref(a)])
10691039
return [x() for x in siblings]
10701040

0 commit comments

Comments
 (0)