Comments
Patch
@@ -2638,14 +2638,53 @@ class _diffset(_lazysetiteratormixin):
def _iterator(self):
if self._iter is None:
def gen():
- # We could further optimize this if r2 is ordered. See
- # _addset._iterator for inspiration.
- s = self._r2.set()
- for r in self._r1:
- if r not in s:
- yield r
+ if self._ascending is None:
+ s = self._r2.set()
+ for r in self._r1:
+ if r not in s:
+ yield r
+ else:
+ iter1 = iter(self._r1)
+ iter2 = iter(self._r2)
+
+ val1 = None
+ val2 = None
+ ascending = self._ascending
+
+ try:
+ while True:
+ if val1 is None:
+ val1 = iter1.next()
+ if val2 is None:
+ val2 = iter2.next()
+
+ # Item appearing in both sets is cancelled out.
+ if val1 == val2:
+ val1 = None
+ val2 = None
+ continue
+
+ if ascending:
+ if val1 < val2:
+ yield val1
+ val1 = None
+ else:
+ val2 = None
+ else:
+ if val1 > val2:
+ yield val1
+ val1 = None
+ else:
+ val2 = None
+ except StopIteration:
+ # Flush any remaining values from the original set.
+ # Values from the subtracting set are irrelevant.
+ if val1 is not None:
+ yield val1
+ for val in iter1:
+ yield val
self._iter = _generatorset(gen())
return self._iter