API Reference
Preface
The usage of the library usually follows the following pattern:
- Create a loop using one of the factory functions (which return a
Loop
instance). - Apply one or more modifier methods (in a method chaining style) to customize the looping behaviour.
- Finally, consume the loop, for example using a
for
statement.
Factory Functions
loop.loop_over(iterable)
Construct a new Loop
that iterates over iterable
.
Customize the looping behaviour by chaining different Loop
methods and finally use a for
statement like you normally would.
Example
from loop import loop_over
for word in loop_over(['Hello', 'World', '!']):
print(word)
Hello
World
!
PARAMETER | DESCRIPTION |
---|---|
iterable |
The object to be looped over.
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
Loop[S, S, FALSE, FALSE, TRUE]
|
Returns a new |
loop.loop_range(*args)
Shorthand for loop_over(range(*args))
.
Modifier Methods
loop.Loop.map(function, *args, **kwargs)
Apply function
to each item
in iterable
by calling function(item, *args, **kwargs)
.
Example
from loop import loop_over
for word in loop_over(['Hello', 'World', '!']).map(lambda s: s.upper()):
print(word)
HELLO
WORLD
!
PARAMETER | DESCRIPTION |
---|---|
function |
Function to be applied on each item in the loop.
TYPE:
|
args |
Passed as
DEFAULT:
|
kwargs |
Passed as
DEFAULT:
|
Note
By default, applying map(function, *args, **kwargs)
is not the same as applying map(functools.partial(function, *args, **kwargs))
because functools.partial
would pass *args
BEFORE the loop item.
loop.Loop.filter(predicate, *args, **kwargs)
Skip item
s in iterable
for which predicate(item, *args, **kwargs)
is false.
Example
from loop import loop_over
for number in loop_over(range(10)).filter(lambda x: x%2==0):
print(number)
0
2
4
6
8
PARAMETER | DESCRIPTION |
---|---|
predicate |
Function that accepts the loop variable and returns a boolean.
TYPE:
|
args |
Passed as
DEFAULT:
|
kwargs |
Passed as
DEFAULT:
|
Note
If show_progress()
was enabled with a known total
, each time an item is skipped, the progress bar's total
will be reduced by one.
loop.Loop.next_call_with(unpacking=None, args_first=False)
Change how arguments are passed to function
in map()
(or predicate
in filter()
).
Arguments are explained using the following table:
unpacking |
args_first |
Resulting Call |
---|---|---|
None |
False |
func(x, *args, **kwargs) (this is the default behaviour) |
None |
True |
func(*args, x, **kwargs) |
"*" |
False |
func(*x, *args, **kwargs) |
"*" |
True |
func(*args, *x, **kwargs) |
"**" |
Any |
func(*args, **x, **kwargs) |
Note
Each invocation of next_call_with()
applies only to the next map()
/filter()
, subsequent calls will resume to default behaviour.
loop.Loop.returning(enumerations=False, inputs=False, outputs=True)
Set the return type of this loop.
By default, only outputs are returned.
The order of returned items is (enumerations, inputs, outputs)
.
Example
from loop import loop_over
for retval in loop_over(range(0, 10, 2)).map(pow, 2).returning(enumerations=True, inputs=True, outputs=True):
print(retval)
(0, 0, 0)
(1, 2, 4)
(2, 4, 16)
(3, 6, 36)
(4, 8, 64)
PARAMETER | DESCRIPTION |
---|---|
enumerations |
If True, return value will include the (zero-based) index of the current iteration.
TYPE:
|
inputs |
If True, return value will include the raw value from the underlying iterable, before any
TYPE:
|
outputs |
If True, return value will include the output of the last
TYPE:
|
loop.Loop.show_progress(refresh=False, postfix_str=None, total=None, **kwargs)
Display a tqdm.tqdm
progress bar as the iterable is being consumed.
Example
import time
from loop import loop_over
seconds = [1.1, 4.5, 0.9, 5.8]
loop_over(seconds).map(time.sleep).show_progress(desc='Sleeping', total=len).exhaust()
Sleeping: 100%|█████████████████████████████████████████| 4/4 [00:12<00:00, 3.08s/it]
PARAMETER | DESCRIPTION |
---|---|
refresh |
If True,
TYPE:
|
postfix_str |
Used for calling
TYPE:
|
total |
Same as in
TYPE:
|
kwargs |
Forwarded to
DEFAULT:
|
Note
When postfix_str
is callable, it always takes a single parameter, the value of which depends on what was set in returning()
.
For example:
(loop_over(...).
returning(enumerations=True, inputs=True, outputs=True).
show_progress(postfix_str=lambda x: f'idx={x[0]},inp={x[1]},out={x[2]}'))
Here x
is a tuple containing the current index, input and output.
loop.Loop.concurrently(how, exceptions='raise', chunksize=None, num_workers=None)
Apply the functions and predicates from all map()
and filter()
calls concurrently.
The order of the outputs is preserved. Each item
in iterable
gets its own worker.
Example
import os
import time
from loop import loop_over
def show_pid(i):
time.sleep(0.1)
print(f'{i} on process {os.getpid()}')
loop_over(range(10)).map(show_pid).concurrently('processes', num_workers=5).exhaust()
0 on process 17336
1 on process 17320
2 on process 13960
3 on process 5136
4 on process 17224
5 on process 17336
7 on process 13960
6 on process 17320
8 on process 5136
9 on process 17224
PARAMETER | DESCRIPTION |
---|---|
how |
If If
TYPE:
|
exceptions |
If If
TYPE:
|
chunksize |
Passed to This is used to consume (and concurrently process) up to
TYPE:
|
num_workers |
Number of workers to be used in the process/thread pool. If
TYPE:
|
Consumer Methods
loop.Loop.__iter__()
The most common way to consume a loop is to simply iterate over it.
Example
from loop import loop_over
items = ...
for item in loop_over(items):
# Do something with item
pass
loop.Loop.exhaust()
Consume the loop without returning any results.
This maybe useful when you map functions only for their side effects.
Example
from loop import loop_over
items = []
loop_over(range(5)).map(items.append).exhaust()
print(items)
[0, 1, 2, 3, 4]
loop.Loop.reduce(function, initializer=_missing)
Consume the loop and reduce it to a single value using function
.
function
and (the optional) initializer
have the same
meaning as in functools.reduce()
.
Example
from loop import loop_over
vec = [-1.1, 25.3, 4.9]
sum_squares = loop_over(vec).map(lambda x: x**2).reduce(lambda x,y: x+y)
print(f'The L2 norm of {vec} equals {sum_squares**0.5:.2f}')
The L2 norm of [-1.1, 25.3, 4.9] equals 25.79