Package: lazy-streams
Python lazy_streamsInspired by Java 8's streams, this Python module provides a fluent syntax for
manipulating and querying Python lists.  It's calledlazy_streams because
it lazy-evaluates the requests to increase performance and decrease resource
requirements.Here's a quick example:>>> from lazy_streams import stream
>>> data = range(100)
>>> s = stream(data)
>>> print s \
...     .reverse() \
...     .filter(lambda x: (x+1)%2 == 0) \
...     .map(lambda x: x*x) \
...     .map(lambda x: "Item %d" % x) \
...     .last_or_else("Nothing here")
Item 1
>>>Lazy_streams is intended to be a small (single-file), light-weight, simple
implementation that depends only the Python standard library.As you can see from the above example, you can stack multiple manipulations
on top of each other.  The module will optimize the execution to only perform
the operations on the elements of the list that are involved in the eventual
output.Also, the original list will remain unchanged as the output of each operation
simply returns a delta from the original value.Operations on a LazyStream can be categories into two groups:  Terminal
operations and Non-terminal operations.  Terminal operations result in a
concrete result (a value, a list, etc.).  Non-terminal operations will return
a new LazyStream.Terminal operationsto_list(threads=0)- Will convert the stream back to a list. Returns alist.  Ifthreadsis 0, to_list will create the list serially on the
main thread.  Ifthreadsis greater than 0, to_list will be generated
in parallel using the number of threads specified.>>> print(stream(range(10)).to_list())
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>*NOTE:using threads is computationally expensive and won't
necessarily speed up your work.  It is intended to be used to speed up
time-consuming map and filter processes (making web service calls for
example).  If your map/filter functions aren't doing anything time-
sensitive, you'll probably get more speed leavingthreadsat 0.to_string(separator=', ', threads=0)- Will convert the list to a string
by joining the elements using the given separator (defaults to ', '). Returns
astring.>>> print(stream(range(10)).to_string())
'0, 1, 2, 3, 4, 5, 6, 7, 8, 9'
>>> print(stream(range(10)).to_string('-'))
'0-1-2-3-4-5-6-7-8-9'
>>>first_or_else(or_else=None)- Will return the first item in the resulting
list.  If the resulting list is empty, returns the value ofor_else.
Returns avalue.>>> print(stream([5, 6, 7]).first_or_else())
5
>>> print(stream([]).first_or_else())
None
>> print(stream([]).first_or_else(-1))
-1
>>>last_or_else(or_else=None)- Will return the last item in the resulting
list.  If the resulting list is empty, returns the value ofor_else.
Returns avalue.>>> print(stream([5, 6, 7]).first_or_else())
7
>>> print(stream([]).first_or_else())
None
>> print(stream([]).first_or_else(-1))
-1
>>>reduce(func, threads=0)- Calls Python'sreducefunction passing it the
given function and the resulting list of the stream. Returns avalue.>>> print(stream(range(5)).reduce(lambda x,y: x-y))
-10
>>>min(key=None, threads=0)- Sorts the list using the given sort key and then
returns the first item in the rsulting list. Returns avalue.>>> print(stream(range(3)).min())
0
>>> print(stream(['Matilda', 'Tom', 'Sally']).min(key=lambda x: len(x)))
'Tom'
>>>max(key=None, threads=0)- Sorts the list using the given sort key and then
returns the last item in the resulting list. Returns avalue.>>> print(stream(range(3)).max())
2
>>> print(stream(['Matilda', 'Tom', 'Sally']).max(key=lambda x: len(x)))
'Matilda'
>>>size(threads=0)- Returns the number of items in the Streams's resulting
list.>>> print(stream([5, 6, 7]).size())
3
>>>Non-terminal operationsNon-terminal operations return a new LazyStream as their result.  This allows
you to stack multiple operations up together.#!/usr/bin/env python
from lazy_streams import stream

names = stream(['Bob', 'Sally', 'Jane', 'Joe', 'Emily', 'Jake', 'John']) \
    .filter(lambda x: len(x) > 3) \
    .sort() \
    .map(lambda x: "First name: %s" % x) \
    .to_string("\n")
print(names)

... outputs ...

First name: Emily
First name: Jake
First name: Jane
First name: John
First name: Sallytake(num_items)- Will return a new LazyStream that only contains the
firstnum_itemsitem from the called upon stream.>>> print stream([1, 2, 3, 4]).take(2).to_list()
[1, 2]
>>>flatten()- Will flatten a list-of-lists to a flat list.>>> print(stream([1, [2, 3], 4, [[5, 6], 7]]).flatten().to_list())
[1, 2, 3, 4, 5, 6, 7]
>>>sort(key=None, reverse=False)- Will return a sorted Stream using the given
key.  Ifreverseis true, will reverse the sort.>>> print(stream([3, 5, 7, 2, 4, 6]).sort().to_list())
[2, 3, 4, 5, 6, 7]
>>> print(stream(['AAA', 'AA', 'AAA', 'A']).sort(key=lambda x: len(x), reverse=True).to_list())
['AAA', 'AAA', 'AA', 'A']map(func)- Will callfuncon each item of the stream's list and return
the result.>>> print(stream([2, 3, 4]).map(lambda x: x*2).to_list())
[4, 6, 8]
>>>filter(func)- Will callfuncon each item of the stream's list and only
keep the ones wherefuncreutrns True.>>> print(stream(['A', 'AAAAA', 'AAA', 'AA']).filter(lambda x: len(x) > 2).to_list())
['AAAAA', 'AAA']
>>>reverse()- Will simply reverse the order of the items.  This operation does
not perform any sorting.  It simply mirrors the values.>>> print(stream(['Gus', 'Joe', 'Sally', 'Mike', 'Jane']).reverse().to_list())
['Jane', 'Mike', 'Sally', 'Joe', 'Gus']
>>>