[Jython-checkins] jython: Add itertools.combinations

jim.baker jython-checkins at python.org
Thu Mar 15 05:23:13 CET 2012


http://hg.python.org/jython/rev/1240d250d386
changeset:   6386:1240d250d386
parent:      6374:2538e8ea568f
user:        Jim Baker <jbaker at zyasoft.com>
date:        Wed Mar 14 16:23:22 2012 -0700
summary:
  Add itertools.combinations

files:
  .idea/workspace.xml                   |  122 +++++++++++-
  src/org/python/modules/itertools.java |  136 ++++---------
  2 files changed, 158 insertions(+), 100 deletions(-)


diff --git a/.idea/workspace.xml b/.idea/workspace.xml
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -1,7 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="ChangeListManager">
-    <list default="true" id="bce1b1d0-380f-4885-b052-d71e69b3b8fa" name="Default" comment="" />
+    <list default="true" id="bce1b1d0-380f-4885-b052-d71e69b3b8fa" name="Default" comment="">
+      <change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/org/python/modules/itertools.java" afterPath="$PROJECT_DIR$/src/org/python/modules/itertools.java" />
+    </list>
     <ignored path="jython27.iws" />
     <ignored path=".idea/workspace.xml" />
     <option name="TRACKING_ENABLED" value="true" />
@@ -76,15 +78,42 @@
       <file leaf-file-name="itertools.java" pinned="false" current="true" current-in-tab="true">
         <entry file="file://$PROJECT_DIR$/src/org/python/modules/itertools.java">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="775" column="112" selection-start="29116" selection-end="29116" vertical-scroll-proportion="0.44174758">
+            <state line="713" column="51" selection-start="26768" selection-end="26768" vertical-scroll-proportion="0.024752475">
               <folding>
                 <element signature="imports" expanded="true" />
-                <element signature="e#4777#4787#0" expanded="true" />
+                <element signature="e#4845#4855#0" expanded="true" />
               </folding>
             </state>
           </provider>
         </entry>
       </file>
+      <file leaf-file-name="PyIterator.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/org/python/core/PyIterator.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="13" column="22" selection-start="551" selection-end="551" vertical-scroll-proportion="0.0">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="__builtin__.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/org/python/core/__builtin__.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="863" column="32" selection-start="30555" selection-end="30560" vertical-scroll-proportion="0.0">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+      <file leaf-file-name="PyTeeIterator.java" pinned="false" current="false" current-in-tab="false">
+        <entry file="file://$PROJECT_DIR$/src/org/python/modules/PyTeeIterator.java">
+          <provider selected="true" editor-type-id="text-editor">
+            <state line="16" column="13" selection-start="492" selection-end="492" vertical-scroll-proportion="0.0">
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
       <file leaf-file-name="Py.java" pinned="false" current="false" current-in-tab="false">
         <entry file="file://$PROJECT_DIR$/src/org/python/core/Py.java">
           <provider selected="true" editor-type-id="text-editor">
@@ -97,7 +126,7 @@
       <file leaf-file-name="IdImpl.java" pinned="false" current="false" current-in-tab="false">
         <entry file="file://$PROJECT_DIR$/src/org/python/core/IdImpl.java">
           <provider selected="true" editor-type-id="text-editor">
-            <state line="84" column="35" selection-start="2215" selection-end="2235" vertical-scroll-proportion="0.0">
+            <state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0">
               <folding />
             </state>
           </provider>
@@ -182,6 +211,60 @@
               <option name="myItemType" value="" />
             </PATH_ELEMENT>
           </PATH>
+          <PATH>
+            <PATH_ELEMENT USER_OBJECT="Root">
+              <option name="myItemId" value="" />
+              <option name="myItemType" value="" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT USER_OBJECT="jython27">
+              <option name="myItemId" value="" />
+              <option name="myItemType" value="" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT USER_OBJECT="src">
+              <option name="myItemId" value="" />
+              <option name="myItemType" value="" />
+            </PATH_ELEMENT>
+          </PATH>
+          <PATH>
+            <PATH_ELEMENT USER_OBJECT="Root">
+              <option name="myItemId" value="" />
+              <option name="myItemType" value="" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT USER_OBJECT="jython27">
+              <option name="myItemId" value="" />
+              <option name="myItemType" value="" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT USER_OBJECT="src">
+              <option name="myItemId" value="" />
+              <option name="myItemType" value="" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT USER_OBJECT="org/python">
+              <option name="myItemId" value="" />
+              <option name="myItemType" value="" />
+            </PATH_ELEMENT>
+          </PATH>
+          <PATH>
+            <PATH_ELEMENT USER_OBJECT="Root">
+              <option name="myItemId" value="" />
+              <option name="myItemType" value="" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT USER_OBJECT="jython27">
+              <option name="myItemId" value="" />
+              <option name="myItemType" value="" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT USER_OBJECT="src">
+              <option name="myItemId" value="" />
+              <option name="myItemType" value="" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT USER_OBJECT="org/python">
+              <option name="myItemId" value="" />
+              <option name="myItemType" value="" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT USER_OBJECT="modules">
+              <option name="myItemId" value="" />
+              <option name="myItemType" value="" />
+            </PATH_ELEMENT>
+          </PATH>
         </subPane>
       </pane>
     </panes>
@@ -362,13 +445,13 @@
       <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
       <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
       <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="true" content_ui="tabs" />
-      <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.24918832" sideWeight="0.5129376" order="2" side_tool="true" content_ui="tabs" />
+      <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24918832" sideWeight="0.5129376" order="2" side_tool="true" content_ui="tabs" />
       <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="7" side_tool="false" content_ui="tabs" />
       <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
       <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24959481" sideWeight="0.49467275" order="1" side_tool="true" content_ui="tabs" />
       <window_info id="Maven Projects" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
       <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
-      <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" weight="0.24918832" sideWeight="0.47640792" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.24918832" sideWeight="0.47640792" order="0" side_tool="false" content_ui="tabs" />
       <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
       <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
       <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
@@ -447,19 +530,40 @@
         </state>
       </provider>
     </entry>
+    <entry file="file://$PROJECT_DIR$/src/org/python/modules/PyTeeIterator.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="16" column="13" selection-start="492" selection-end="492" vertical-scroll-proportion="0.0">
+          <folding />
+        </state>
+      </provider>
+    </entry>
     <entry file="file://$PROJECT_DIR$/src/org/python/core/IdImpl.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="84" column="35" selection-start="2215" selection-end="2235" vertical-scroll-proportion="0.0">
+        <state line="0" column="0" selection-start="0" selection-end="0" vertical-scroll-proportion="0.0">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/org/python/core/__builtin__.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="863" column="32" selection-start="30555" selection-end="30560" vertical-scroll-proportion="0.0">
+          <folding />
+        </state>
+      </provider>
+    </entry>
+    <entry file="file://$PROJECT_DIR$/src/org/python/core/PyIterator.java">
+      <provider selected="true" editor-type-id="text-editor">
+        <state line="13" column="22" selection-start="551" selection-end="551" vertical-scroll-proportion="0.0">
           <folding />
         </state>
       </provider>
     </entry>
     <entry file="file://$PROJECT_DIR$/src/org/python/modules/itertools.java">
       <provider selected="true" editor-type-id="text-editor">
-        <state line="775" column="112" selection-start="29116" selection-end="29116" vertical-scroll-proportion="0.44174758">
+        <state line="713" column="51" selection-start="26768" selection-end="26768" vertical-scroll-proportion="0.024752475">
           <folding>
             <element signature="imports" expanded="true" />
-            <element signature="e#4777#4787#0" expanded="true" />
+            <element signature="e#4845#4855#0" expanded="true" />
           </folding>
         </state>
       </provider>
diff --git a/src/org/python/modules/itertools.java b/src/org/python/modules/itertools.java
--- a/src/org/python/modules/itertools.java
+++ b/src/org/python/modules/itertools.java
@@ -4,6 +4,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.python.core.__builtin__;
 import org.python.core.ArgParser;
 import org.python.core.ClassDictInit;
 import org.python.core.Py;
@@ -16,6 +17,8 @@
 import org.python.core.PyTuple;
 import org.python.core.PyXRange;
 
+import java.util.Arrays; //XXX
+
 /**
  * Functional tools for creating and using iterators. Java implementation of the CPython module
  * itertools.
@@ -713,53 +716,48 @@
         return tee(iterable, 2);
     }
 
-//    classmethod chain.from_iterable(iterable)
-//
-//    Alternate constructor for chain(). Gets chained inputs from a single iterable argument that is evaluated lazily. Equivalent to:
-//
-//    @classmethod
-//    def from_iterable(iterables):
-//            # chain.from_iterable(['ABC', 'DEF']) --> A B C D E F
-//    for it in iterables:
-//            for element in it:
-//    yield element
+//chain.from_iterable(iterable)
+//combinations(iterable, r):
 
-//    def combinations(iterable, r):
-//            # combinations('ABCD', 2) --> AB AC AD BC BD CD
-//    # combinations(range(4), 3) --> 012 013 023 123
-//    pool = tuple(iterable)
-//    n = len(pool)
-//    if r > n:
-//            return
-//    indices = range(r)
-//    yield tuple(pool[i] for i in indices)
-//    while True:
-//            for i in reversed(range(r)):
-//            if indices[i] != i + n - r:
-//            break
-//            else:
-//            return
-//    indices[i] += 1
-//            for j in range(i+1, r):
-//    indices[j] = indices[j-1] + 1
-//    yield tuple(pool[i] for i in indices)
+    public static PyIterator combinations(PyObject iterable, final int r) {
+        final PyTuple pool = PyTuple.fromIterable(iterable);
+        final int n = pool.__len__();
+        final int indices[] = new int[r];
+        for (int i = 0; i < r; i++) {
+            indices[i] = i;
+        }
 
-//def combinations_with_replacement(iterable, r):
-//            # combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
-//    pool = tuple(iterable)
-//    n = len(pool)
-//    if not n and r:
-//            return
-//    indices = [0] * r
-//    yield tuple(pool[i] for i in indices)
-//    while True:
-//            for i in reversed(range(r)):
-//            if indices[i] != n - 1:
-//            break
-//            else:
-//            return
-//    indices[i:] = [indices[i] + 1] * (r - i)
-//    yield tuple(pool[i] for i in indices)
+        return new ItertoolsIterator() {
+            boolean firstthru = true;
+
+            @Override
+            public PyObject __iternext__() {
+                if (r > n) { return null; }
+                if (firstthru) {
+                    firstthru = false;
+                    return makeTuple();
+                }
+                int i;
+                for (i = r-1; i >= 0 && indices[i] == i+n-r ; i--);
+                if (i < 0) return null;
+                indices[i]++;
+                for (int j = i+1; j < r; j++) {
+                    indices[j] = indices[j-1] + 1;
+                }
+                return makeTuple();
+            }
+            
+            private PyTuple makeTuple() {
+                PyObject items[] = new PyObject[r];
+                for (int i = 0; i < r; i++) {
+                    items[i] = pool.__getitem__(indices[i]);
+                }                                 
+                return new PyTuple(items);
+            }
+        };
+    }
+
+//combinations_with_replacement(iterable, r):
 
     public static PyString __doc__compress = new PyString(
         "compress(data, selectors) --> iterator over selected data\n\n" +
@@ -777,9 +775,11 @@
 
         return new ItertoolsIterator() {
 
+            @Override
             public PyObject __iternext__() {
                 while (true) {
                     PyObject datum = nextElement(data);
+                    if (datum == null) { return null; }
                     PyObject selector = nextElement(selectors);
                     if (selector == null) { return null; }
                     if (selector.__nonzero__()) {
@@ -794,50 +794,4 @@
         };
     }
 
-
-//class ZipExhausted(Exception):
-//    pass
-//
-//def izip_longest(*args, **kwds):
-//            # izip_longest('ABCD', 'xy', fillvalue='-') --> Ax By C- D-
-//    fillvalue = kwds.get('fillvalue')
-//    counter = [len(args) - 1]
-//    def sentinel():
-//            if not counter[0]:
-//    raise ZipExhausted
-//    counter[0] -= 1
-//    yield fillvalue
-//    fillers = repeat(fillvalue)
-//    iterators = [chain(it, sentinel(), fillers) for it in args]
-//            try:
-//            while iterators:
-//    yield tuple(map(next, iterators))
-//    except ZipExhausted:
-//    pass
-
-//def permutations(iterable, r=None):
-//            # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
-//    # permutations(range(3)) --> 012 021 102 120 201 210
-//    pool = tuple(iterable)
-//    n = len(pool)
-//    r = n if r is None else r
-//    if r > n:
-//            return
-//    indices = range(n)
-//    cycles = range(n, n-r, -1)
-//    yield tuple(pool[i] for i in indices[:r])
-//    while n:
-//            for i in reversed(range(r)):
-//    cycles[i] -= 1
-//            if cycles[i] == 0:
-//    indices[i:] = indices[i+1:] + indices[i:i+1]
-//    cycles[i] = n - i
-//    else:
-//    j = cycles[i]
-//    indices[i], indices[-j] = indices[-j], indices[i]
-//    yield tuple(pool[i] for i in indices[:r])
-//    break
-//            else:
-//            return
-
 }

-- 
Repository URL: http://hg.python.org/jython


More information about the Jython-checkins mailing list