Reference - Mercerenies/alakazam GitHub Wiki
Function Reference
Alakazam Methods
The Alakazam
class, usually referred to in its abbreviated form
ZZ
, provides method versions of built-in Python functional
procedures, as well as providing method versions of the itertools
functions.
- Construction
- Magic Methods
- Transformers
- Producers
- Reducers
- Conversions
- Tracing Functions
- Miscellaneous
Construction
Alakazam(iterable)
Constructs an Alakazam
object which wraps the iterable. As with most
Python iteration tools, if the iterable argument was in fact an
iterator, the iterator should not be modified or advanced of its own
accord once it is owned by an Alakazam
instance.
AlakazamError(msg)
Constructs an AlakazamError
, which is used for reporting Alakazam
errors. You should not need to call this directly.
Magic Methods
iter(zz)
reversed(zz)
len(zz)
Attempting to perform any of these operations on an Alakazam
instance will simply delegate to the underlying iterable.
str(zz)
repr(zz)
Alakazam provides simple string representations, based on the representation of the underlying type.
Transformers
Note: All of these transformers return a new Alakazam
object.
zz.map(func, *iters)
Maps a function over each element of the iterable. If multiple
iterables are passed, they will be zipped together and the function
will be applied to elements of each of them. This behavior is
consistent with the built-in Python map
function.
zz.filter(func)
Returns a new iterable which contains only the elements of the original for which the 1-ary predicate returned true.
zz.islice([start,] stop [, step])
Returns a sliced iterable, containing every Nth (where N is the step
argument) element from start
to stop
(inclusive and exclusive,
respectively). The start
, stop
, and step
values should all be
nonnegative integers, with the exception that stop
can be
None
. The default values for start
and step
are 0
and 1
,
respectively. If stop
is None
, the slice continues until the end
of the iterable.
zz.take(n)
Returns an Alakazam iterable taking the first n
elements. If n
is
greater than the length of the iterable, take
returns a new iterable
over the same elements.
zz.drop(n)
Returns an Alakazam iterable containing all but the first n
elements. If n
is greater than the length of the iterable, an empty
Alakazam iterable is returned.
zz.accumulate(func = None, init = <impl_defined>)
Returns an Alakazam iterable accumulating the values of the original
iterable. The function, if non-None
, should be a 2-ary function. If
the function is None
, it defaults to operator.__add__
. The first
element of the returned iterable is the first element of the original
iterable. Every subsequent element is the result of calling func
with the previous accumulated element and the current element of the
original iterable, so ZZ([a, b, c, d]).accumulate()
yields an
iterable whose underlying list is [a, a + b, a + b + c, a + b + c + d]
. If an init
argument is provided, it will be prepended to the
list before iteration.
zz.chain(*args)
Chains together multiple iterables into one Alakazam iterable. The calling object will be the first iterable to be included in the chain, followed by each of the arguments in order.
zz.chain_lazy(iterable)
Chains together an iterable of iterables. This behaves identically to
zz.chain
except that it takes a single argument which is
iterable. This method is useful if you wish to chain together an
infinite sequence of iterables.
zz.compress(sel)
Keeps only the elements of the Alakazam iterable for which the
corresponding element of the sel
iterable is truthy. So ZZ([a, b, c, d]).compress([0, 1, 1, 0])
would return an iterable containing the
elements [a, d]
. The compress
method stops when either the Alakazam
iterable or the selector iterable is exhausted.
zz.dropwhile(pred)
Drops elements from the beginning of the iterable as long as the 1-ary predicate returns true.
zz.filterfalse(pred)
Returns a new iterable which contains only the elements of the original for which the 1-ary predicate returned false.
zz.groupby(key = None)
Groups consecutive elements of the iterable together, breaking into a
new group whenever the 1-ary key
function returns a different
value. If key
is None
, it defaults to the identity function. The
individual returned groups are ordinary Python lists, not Alakazam
objects.
zz.starmap(func)
Maps a function over each element of the iterable, applying the
function to each element using argument unpacking. That is,
zz.starmap(f)
behaves equivalently to zz.map(lambda x: f(*x))
.
zz.takewhile(pred)
Takes the longest prefix for which every element in the prefix
satisfies the 1-ary predicate pred
.
zz.enumerate(start = 0)
Pairs each element of the iterable with its index value, starting at start
.
zz.group(n)
Groups every n
elements of the iterable into a new sublist,
returning an iterable of sublists. So ZZ([1, 2, 3, 4, 5]).group(2)
returns an iterable whose list representation is [[1, 2], [3, 4], [5]]
. The individual returned groups are ordinary Python lists, not
Alakazam objects.
zz.zip(*args)
Zips the calling iterable together with all of the argument iterables, returning an iterable of tuples. Stops when any of the iterables is exhausted.
zz.zip_longest(*args, fillvalue = None)
Zips the calling iterable together with all of the argument iterables,
returning an iterable of tuples. Stops when all of the iterables are
exhausted. When the shorter iterables are exhausted, their positions
in the tuple will be padded with fillvalue
.
zz.flatten()
Flattens one layer of the iterable, which should itself contain iterable values.
zz.cross_product(*args, repeat = 1)
zz.permutations(r = None)
zz.combinations(r)
zz.combinations_with_replacement(r)
These four methods behave identically to the itertools
functions
with the same names, except that these return Alakazam
objects. Note
that cross_product
behaves like itertools.product
, as Alakazam's
product
method does something different.
zz.cycle()
Returns an iterable containing all of the elements of the iterable, repeated infinitely. If the calling iterable is empty then the resulting iterable will also be empty.
zz.reversed()
Produces a new Alakazam iterable containing the reversed version of
the current iterable. This method's behavior is only defined if
calling reversed
on the caller's iterable is well-defined.
zz.withobject(obj)
Returns a new Alakazam iterable in which every element of the current
iterable has been paired with the given element. That is, zz.of([1, 2, 3]).withobject(-1)
produces an iterable whose elements are (0, 1)
, (0, 2)
, and (0, 3)
.
zz.interlace(*args)
Returns a new Alakazam iterable which contains the first element of each of the iterables, followed by the second of each, then the third, and so on. The resulting iterable terminates when any of the inner iterables terminates, which may result in a "partial" collection of elements at the end, if one of the later iterables terminates before the first.
zz.intersperse(obj)
Returns an Alakazam iterable which produces the same elements as the
current one, but between every pair of elements obj
is inserted. So
zz.of([1, 2, 3]).intersperse(0)
will produce [1, 0, 2, 0, 3]
.
zz.indices(func = None)
Returns a new Alakazam iterable consisting of the indices of the
original iterable which contain values for which func
returns
truthy. If no function is provided, the identity function is assumed,
and the resulting iterable will be all of the indices pointing to
truthy values.
Producers
Note: All of the generators are global functions. For compatibility
with earlier Alakazam versions, these generators are also provided as
static methods on the Alakazam
class, but it is recommended that you
use the global function versions.
count(start, step = 1)
Returns an infinite stream of integers, starting at start
and
counting with step
.
repeat(elem, n = None)
Returns an iterable containing the element elem
, repeated n
times. If n
is None
, the element is repeated forever.
of(value)
This function is equivalent to simply calling the Alakazam
constructor directly, but zz.of
often looks better in a chain of
stream operations than an explicit constructor call.
of_dict(value)
This function generates an Alakazam
instance which iterates over a
dictionary. However, whereas zz.of
will iterate over the keys of a
dictionary, zz.of_dict
iterates over key-value pairs in the form of
2-tuples.
range([start,] stop [, step])
Returns an Alakazam iterable containing a Python range
object.
empty()
Returns an empty Alakazam iterable.
iterate(func, value)
Returns an infinite iterable consisting of successive applications of
the provided function to the given value. That is, the first value in
the resulting iterable is value
, followed by func(value)
, then
func(func(value))
, and so on.
zipup(*args)
Zips all of the iterables together and returns an Alakazam iterable
containing the zipped result, as though through zip
.
Reducers
Note: Reducers do NOT return Alakazam
instances; they return scalar
values computed based on elements of the iterable.
zz.reduce(func, init = <impl_defined>)
This method behaves like the functools.reduce
function.
zz.foldl(func, init = <impl_defined>)
This method is identical to reduce
. This version of the method
should be used in cases where the operation is non-associative, to
make the folding order explicit.
zz.foldr(func, init = <impl_defined>)
This method behaves like foldl
except that it associates to the
right. The init
value, if supplied, is placed at the end of the
iterable and folded in with it. With foldr
, the accumulator is
always the second argument passed to the function, not the first.
If the iterable supports reversal (i.e.
reversed
doesn't raise an exception), then foldr
will reverse the structure
first and then iterate in order, using constant call stack space.
However, if the iterable does not support reversal, then foldr
will
fall back to a non-tail recursive implementation which can easily blow
up your call stack.
zz.foldr_lazy(func, init = <impl_defined>)
One of the primary advantages to foldr
in a functional language is
that it can lazily terminate for infinite sequences if it determines
that it does not need any further elements. This version of foldr
implements a lazy form of the fold, allowing early termination. The
function func
should take two arguments. The first argument will be
the current iterable element, as before. However, the second argument
will be a 0-ary callable object. Calling this object will compute the
accumulator for the remaining elements.Thus, to terminate early,
simply do not call this object.
Note carefully that this function is not tail recursive and can easily
explode your call stack if used recklessly. If the lazy behavior is
not necessary, then consider using foldl
(or foldr
on a reversible
iterable) instead.
zz.absorb(func, init)
For each element of the current iterable, calls the function with two
arguments; the first is init
and the second is the element of the
iterable. The return value of the function is ignored. At the end of
iteration, init
is returned. As such, absorb
is only useful if
func
carries side effects. For example: foo.absorb(zz.set(_1[_2], 0), {})
will make a hash which has keys for each element of foo
defaulted to
zero.
zz.sum(init = 0)
Sums the elements of the iterable together with __add__
.
zz.product(init = 1)
Multiplies the elements of the iterable together with __mul__
.
zz.max(key = None, default = <impl_defined>)
Returns the largest value in the iterable. If there are multiple values which compare equivalent, the first such value is returned. If the iterable is empty, the default value is returned if one is provided, or an exception is raised if one is not. If a key is provided, it will be applied to the operands of all comparisons. The returned value will be an element of the original iterable, not the output of the key function.
zz.min(key = None, default = <impl_defined>)
Returns the smallest value in the iterable. If there are multiple values which compare equivalent, the first such value is returned. If the iterable is empty, the default value is returned if one is provided, or an exception is raised if one is not. If a key is provided, it will be applied to the operands of all comparisons. The returned value will be an element of the original iterable, not the output of the key function.
zz.find(func, default = None)
Applies the 1-ary function func
to each element, returning the first
element for which the function returns true. If no such element is
found, returns default
.
zz.all(func = None)
Returns whether the 1-ary function returns true for every element in
the iterable. If the iterable is infinite, this method will only
return if it finds a case where func
returns false. If func
is
None
, it defaults to the identity function.
zz.any(func = None, default = False)
Invokes the 1-ary function (which defaults to the identity function)
for each element of the iterable. If an element produces a truthy
value from the function, then that truthy value is
returned. Otherwise, the default value is returned. Note that this
differs from the built-in Python any
function, which only returns
the constants True
and False
. This method implements the behavior
of the Common Lisp some
function.
zz.null()
Returns whether or not the iterable is empty. Note that using this
function is significantly better than comparing the length against
zero, as zz.null()
will work even on infinite lists.
zz.length()
Fully expands the iterable and returns its length.
zz.consume()
Fully expands the iterable and returns None
. This is useful if some
of the operations being performed carry side effects and the actual
elements are irrelevant at the end.
zz.string()
Constructs a string from the iterable, which must contain only string
elements. zz.string()
is equivalent to zz.join(delim='')
.
zz.join(delim = ',')
Constructs a string from the iterable, which must contain only string
elements. The delimiter, which defaults to ','
, is used as a separator
between elements.
zz.apply(f, *args, **kwargs)
Applies an arbitrary function to the Alakazam iterable object itself,
passing any additional arguments to the supplied function. That is, if
zz
is some Alakazam iterable object, zz.apply(f, *args, **kwargs)
is equivalent to f(zz, *args, **kwargs)
. Many of the conversions
below can be implemented easily in terms of apply
, and in particular
if you wish to consume the iterable by converting to some custom
container type, you may use apply
to do so.
zz.each(f)
Consumes the entire iterable, calling f
on each element in order and
discarding all of the return values. zz.each
returns None
at the
end of iteration, regardless of the values returned from f
. Note
that this method is strict and will immediately force the underlying
iterable. In particular, if the iterable is infinite, then zz.each
will never return and can only be exited in this case by means of an
exception.
zz.first(default = <impl_defined>)
Returns the first element of the iterable, or the provided default
value if the iterable is empty. If the iterable is empty and no
default value is provided, then this function raises an
AlakazamError
.
zz.index(func = None, default = None)
Returns the first index whose corresponding element in the current
iterable returns truthy under func
. If no such value is found,
returns default
. This method call is equivalent to
zz.indices(func=func).first(default=default)
.
Conversions
zz.list()
zz.tuple()
zz.set()
zz.dict(**kwargs)
zz.sorted(key = None, reverse = False)
Each of these methods calls the Python function with the same name,
passing itself as an argument. These methods come in handy at the end
of Alakazam method call chains, if the desired result is of a specific
type. For instance,
zz.of(some_list).map(f).enumerate().filter(g).list()
flows better
than wrapping the chain of method calls in a list()
call explicitly.
If you have a custom data structure or container type that you want to
convert an Alakazam iterable into, you may either do so explicitly
(MyType(zz.of(some_list).map(f).enumerate().filter(g))
) or use
apply
(zz.of(some_list).map(f).enumerate().filter(g).apply(MyType)
).
In the dict
case, additional keyword arguments that are supplied
will overwrite those in the iterable. In the sorted
case, the
optional keyword arguments, if provided, will be passed on to the
sorted
call.
Tracing Functions
(Note: These functions print something out and then return a chosen
value. They are intended for debugging use, when performing a long
chain of Alakazam commands. Simply insert a trace call somewhere in a
map
or foldl
lambda to see intermediate values as the chain is
being executed.)
zz.trace(arg, res, **kwargs)
Prints arg
and then returns res
. Any keyword arguments are passed
on to print
.
zz.traceid(res, **kwargs)
Prints and then returns res
. Any keyword arguments are passed on to
print
.
zz.tracestack(res, **kwargs)
Prints a stack trace and then returns res
. Any keyword arguments are
passed on to traceback.print_stack
.
Miscellaneous
zz.tee(n = 2)
This method delegates to the itertools.tee
function to generate
multiple iterables tied to the same data. It returns a tuple of
Alakazam
iterables, all pointing to the same underlying data.
zz.split(n)
This method splits the Alakazam iterable into two parts. Conceptually,
it behaves as if called by (tuple(zz.take(n)), zz.drop(n))
but only
iterates the structure once (and thus is applicable for single-pass
iterables such as the return value of map
or filter
).
Specifically, zz.split(n)
returns a 2-tuple, where the first element
is a tuple containing the first n
elements of the iterable and the
second element is an Alakazam iterable consisting of the remaining
elements. If n
is greater than the length of the iterable, then the
former element of the return tuple will contain all elements of the
iterable and the latter will be an empty Alakazam iterable.
id(x)
This is the identity function, which simply returns its argument.
compose(*fs)
Returns a function which is the composition of the functions provided. The rightmost function will be called with all of the arguments intact. All other functions will be called with a single argument: the return value of the previously called function.
raise_(exception = None)
This function behaves like the Python raise
statement except that it
is an expression and not a statement. If exception
is None
then
raise_
re-raises the current exception.
setindex(object, index, value)
getindex(object, index)
delindex(object, index)
These three functions behave like setattr
, getattr
, and delattr
,
respectively, except that they operate on subscripting
(object[index]
), rather than field access (object.attr
).
not_(x)
This function is equivalent to the Boolean not
operator. It returns
the logical negation of its argument.
and_(*xs)
Returns the first falsy value among the arguments, or the final
argument is all values are truthy. If no arguments are provided,
True
is returned.
or_(*xs)
Returns the first truthy value among the arguments, or the final
argument if all values are falsy. If no arguments are provided,
False
is returned.
xor(*xs)
Normalizes all of the arguments to Boolean values and then returns the Boolean exclusive-or of all the values. Specifically, this function returns True if and only if an odd number of the arguments are truthy and False otherwise.
var(x)
set(k, v)
delete(k)
bind(f)
arg(n)
kwarg(k)
These functions all manipulate the anonymous function syntax. See the Anonymous Function Guide for details on their behavior.