Commits

Sergey Astanin committed 156fdb9

Move _SubSequencer, make some methods _private, minor edits in partition()

  • Participants
  • Parent commits 4d55d54

Comments (0)

Files changed (1)

     _range = range
     _imap = map
 
-class _SubSequencer:
-    """
-    Lazily process a sequence in single pass and split into many.
-    Compute all output sequences even if only one of them is consumed.
-    Maintain as many subsequence queues as there are predicate values.
-    """
-    def __init__(self, predicate, sequence):
-        self.predicate = predicate
-        self.subseqs = dict()  # mapping of { predicate_value: subseq }
-        self.seq = iter(sequence)
-
-    def subqueue(self, predicate_value):
-        "Get or create a subsequence queue."
-        if not predicate_value in self.subseqs:
-            subseq = self.subseqs[predicate_value] = collections.deque([])
-        else:
-            subseq = self.subseqs[predicate_value]
-        return subseq
-
-    def subappend(self, predicate_value, item):
-        "Append a processed item to subsequence queue."
-        subseq = self.subqueue(predicate_value)
-        subseq.append(item)
-
-    def subnext(self, predicate_value):
-        "Next value in the subsequence corresponding to predicate_value."
-        subseq = self.subqueue(predicate_value)
-        if subseq:
-            return subseq.popleft()
-        else:  # subsequence queue is empty
-            while True:  # exit on StopIteration
-                n = next(self.seq)
-                pv = self.predicate(n)
-                if pv == predicate_value:
-                    return n
-                else:
-                    self._subappend(pv, n)
-
 def groupby(predicate, sequence, predicate_values=()):
     """
     Split a sequence into subsequences with the same predicate value
     pvals =  uniqkeys() if not predicate_values else predicate_values
     return _imap(lambda k: (k, subsequence(k)), pvals)
 
+# partition can be implemented in terms of groupyby, in just two lines
+# of code, but it appears to be twice as slow
+
+class _SubSequencer:
+    """
+    Lazily process a sequence in single pass and split into many.
+    Compute all output sequences even if only one of them is consumed.
+    Maintain as many subsequence queues as there are predicate values.
+    """
+    def __init__(self, predicate, sequence):
+        self.predicate = predicate
+        self.subseqs = dict()  # mapping of { predicate_value: subseq }
+        self.seq = iter(sequence)
+
+    def _subqueue(self, predicate_value):
+        "Get or create a subsequence queue."
+        if not predicate_value in self.subseqs:
+            subseq = self.subseqs[predicate_value] = collections.deque([])
+        else:
+            subseq = self.subseqs[predicate_value]
+        return subseq
+
+    def _subappend(self, predicate_value, item):
+        "Append a processed item to subsequence queue."
+        subseq = self._subqueue(predicate_value)
+        subseq.append(item)
+
+    def subnext(self, predicate_value):
+        "Next value in the subsequence corresponding to predicate_value."
+        subseq = self._subqueue(predicate_value)
+        if subseq:
+            return subseq.popleft()
+        else:  # subsequence queue is empty
+            while True:  # exit on StopIteration
+                n = next(self.seq)
+                pv = self.predicate(n)
+                if pv == predicate_value:
+                    return n
+                else:
+                    self._subappend(pv, n)
+
 def partition(condition, sequence):
     """
     Split a sequence into two subsequences, in single-pass and preserving order.
     As the function works in single pass, it leads to build-up of both
     subsequences even if only one of them is consumed.
 
-    It is similar to Data.List.partition in Haskell, group-by in
-    Clojure, or running two complementary filters:
+    It is similar to Data.List.partition in Haskell, or running two
+    complementary filters:
 
        from itertools import ifilter, ifilterfalse
        (ifilter(condition, sequence), ifilterfalse(condition, sequence))