[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