org.python.modules.itertools.itertools Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython-slim Show documentation
Show all versions of jython-slim Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
/* Copyright (c) Jython Developers */
package org.python.modules.itertools;
import org.python.core.ClassDictInit;
import org.python.core.Py;
import org.python.core.PyException;
import org.python.core.PyIterator;
import org.python.core.PyNone;
import org.python.core.PyObject;
import org.python.core.PyString;
import org.python.core.PyTuple;
import org.python.core.Visitproc;
/**
* Functional tools for creating and using iterators. Java implementation of the CPython module
* itertools.
*
* @since 2.5
*/
public class itertools implements ClassDictInit {
public static final PyString __doc__ = new PyString(
"Functional tools for creating and using iterators.\n\nInfinite iterators:\n" +
"count([n]) --> n, n+1, n+2, ...\n" +
"cycle(p) --> p0, p1, ... plast, p0, p1, ...\n" +
"repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\n" +
"Iterators terminating on the shortest input sequence:\n" +
"chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...\n" +
"compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n" +
"dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n" +
"groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n" +
"ifilter(pred, seq) --> elements of seq where pred(elem) is True\n" +
"ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n" +
"islice(seq, [start,] stop [, step]) --> elements from seq[start:stop:step]\n" +
"imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n" +
"starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n" +
"tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n" +
"takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n" +
"izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...\n" +
"izip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...\n\n" +
"Combinatoric generators:\n" +
"product(p, q, ... [repeat=1]) --> cartesian product\n" +
"permutations(p[, r])\n" +
"combinations(p, r)\n" +
"combinations_with_replacement(p, r)");
/**
* Iterator base class used by most methods.
*/
static abstract class ItertoolsIterator extends PyIterator {
/**
* Returns the next element from an iterator. If it raises/throws StopIteration just store
* the Exception and return null according to PyIterator practice.
*/
protected PyObject nextElement(PyObject pyIter) {
PyObject element = null;
try {
element = pyIter.__iternext__();//next();
} catch (PyException pyEx) {
if (pyEx.match(Py.StopIteration)) {
// store exception - will be used by PyIterator.next()
stopException = pyEx;
} else {
throw pyEx;
}
}
return element;
}
}
public static void classDictInit(PyObject dict) {
dict.__setitem__("__name__", new PyString("itertools"));
dict.__setitem__("__doc__", __doc__);
dict.__setitem__("chain", chain.TYPE);
dict.__setitem__("combinations", combinations.TYPE);
dict.__setitem__("combinations_with_replacement", combinationsWithReplacement.TYPE);
dict.__setitem__("compress", compress.TYPE);
dict.__setitem__("cycle", cycle.TYPE);
dict.__setitem__("count", count.TYPE);
dict.__setitem__("dropwhile", dropwhile.TYPE);
dict.__setitem__("groupby", groupby.TYPE);
dict.__setitem__("imap", imap.TYPE);
dict.__setitem__("ifilter", ifilter.TYPE);
dict.__setitem__("ifilterfalse", ifilterfalse.TYPE);
dict.__setitem__("islice", islice.TYPE);
dict.__setitem__("izip", izip.TYPE);
dict.__setitem__("izip_longest", izipLongest.TYPE);
dict.__setitem__("permutations", permutations.TYPE);
dict.__setitem__("product", product.TYPE);
dict.__setitem__("repeat", repeat.TYPE);
dict.__setitem__("starmap", starmap.TYPE);
dict.__setitem__("takewhile", takewhile.TYPE);
// Hide from Python
dict.__setitem__("classDictInit", null);
dict.__setitem__("initClassExceptions", null);
}
static int py2int(PyObject obj, int defaultValue, String msg) {
if (obj instanceof PyNone) {
return defaultValue;
} else {
int value = defaultValue;
try {
value = Py.py2int(obj);
}
catch (PyException pyEx) {
if (pyEx.match(Py.TypeError)) {
throw Py.ValueError(msg);
} else {
throw pyEx;
}
}
return value;
}
}
/**
* Iterator base class for iterators returned by ifilter
and
* ifilterfalse
.
*/
static class FilterIterator extends ItertoolsIterator {
private PyObject predicate;
private PyObject iterator;
private boolean filterTrue;
FilterIterator(PyObject predicate, PyObject iterable, boolean filterTrue) {
if (predicate instanceof PyNone) {
this.predicate = null;
} else {
this.predicate = predicate;
}
this.iterator = iterable.__iter__();
this.filterTrue = filterTrue;
}
public PyObject __iternext__() {
while (true) {
PyObject element = nextElement(iterator);
if (element != null) {
// the boolean value of calling predicate with the element
// or if predicate is null/None of the element itself
boolean booleanValue = predicate != null ? predicate
.__call__(element).__nonzero__() : element
.__nonzero__();
if (booleanValue == filterTrue) {
// if the boolean value is the same as filterTrue return
// the element
// for ifilter filterTrue is always true, for
// ifilterfalse always false
return element;
}
} else {
return null;
}
}
}
/* Traverseproc implementation */
@Override
public int traverse(Visitproc visit, Object arg) {
int retVal = super.traverse(visit, arg);
if (retVal != 0) {
return retVal;
}
if (iterator != null) {
retVal = visit.visit(iterator, arg);
if (retVal != 0) {
return retVal;
}
}
return predicate != null ? visit.visit(predicate, arg) : 0;
}
@Override
public boolean refersDirectlyTo(PyObject ob) {
return ob != null && (ob == iterator || ob == predicate ||
super.refersDirectlyTo(ob));
}
}
/**
* Iterator base class used by dropwhile()
and takewhile
.
*/
static class WhileIterator extends ItertoolsIterator {
private PyObject iterator;
private PyObject predicate;
// flag that indicates if the iterator shoul drop or return arguments "while" the predicate is true
private boolean drop;
// flag that is set once the predicate is satisfied
private boolean predicateSatisfied;
WhileIterator(PyObject predicate, PyObject iterable, boolean drop) {
this.predicate = predicate;
iterator = iterable.__iter__();
this.drop = drop;
}
public PyObject __iternext__() {
while (true) {
PyObject element = nextElement(iterator);
if (element != null) {
if (!predicateSatisfied) {
// the predicate is not satisfied yet (or still satisfied in the case of drop beeing
// false), so we need to check it
if (predicate.__call__(element).__nonzero__() != drop) {
predicateSatisfied = drop;
return element;
}
predicateSatisfied = !drop;
} else {
if (drop) {
return element;
} else {
// end iteration if predicate is false and drop is false
return null;
}
}
} else {
// end iteration
return null;
}
}
}
/* Traverseproc implementation */
@Override
public int traverse(Visitproc visit, Object arg) {
int retVal = super.traverse(visit, arg);
if (retVal != 0) {
return retVal;
}
if (iterator != null) {
retVal = visit.visit(iterator, arg);
if (retVal != 0) {
return retVal;
}
}
return predicate != null ? visit.visit(predicate, arg) : 0;
}
@Override
public boolean refersDirectlyTo(PyObject ob) {
return ob != null && (ob == iterator || ob == predicate ||
super.refersDirectlyTo(ob));
}
}
public static PyString __doc__tee = new PyString(
"tee(iterable, n=2) --> tuple of n independent iterators.");
/**
* Create a tuple of iterators, each of which is effectively a copy of iterable.
*/
public static PyTuple tee(PyObject iterable, final int n) {
return new PyTuple(PyTeeIterator.makeTees(iterable, n));
}
/**
* Create a pair of iterators, each of which is effectively a copy of iterable.
*/
public static PyTuple tee(PyObject iterable) {
return tee(iterable, 2);
}
static PyTuple makeIndexedTuple(PyTuple pool, int indices[]) {
return makeIndexedTuple(pool, indices, indices.length);
}
static PyTuple makeIndexedTuple(PyTuple pool, int indices[], int end) {
PyObject items[] = new PyObject[end];
for (int i = 0; i < end; i++) {
items[i] = pool.__getitem__(indices[i]);
}
return new PyTuple(items);
}
}