# Lazy Stream
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)
Lazy Stream is a library for lazy evaluation in Python, inspired by the Scala Stream class.
Lazy Stream allows you to store and chain operations on a finite or infinite sequence of values. The final result will only be computed when needed, for better memory and performance over conventional Python lists.
## Installation
Lazy Stream can be installed via pip:
```bash
pip install lazystream
```
## Usage
Lazy Stream supports basic stream operations and parallelism. Below is a quick overview of the current features. Feel free to request additional features.
### Creation
Lazy Stream is very easy to use. You can create a stream from any function or iterator and obtain the results via `evaluate`. Finite and infinite streams are supported, but care must be taken when using infinite streams to avoid infinite operation.
```python
from lazystream import LazyStream
# Finite stream from iterator
incremental_stream = LazyStream.from_iterator(iter(range(5)))
incremental_stream.evaluate()
# [0, 1, 2, 3, 4]
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
# Infinite stream from function-defined iterator
fibo_stream = LazyStream.from_iterator(fibonacci())
fibo_stream.evaluate(5)
# [0, 1, 1, 2, 3]
fibo_stream.evaluate()
# Unsafe, will never terminate
```
You can also create a stream from a function, which will be evaluated lazily:
```python
import random
from lazystream import LazyStream
# Infinite streams from function
random_stream = LazyStream.from_lambda(lambda: random.randint(0, 100))
```
### Operations
You can chain operations on streams, which will be evaluated lazily. Classic stream-compatible operations are supported, such as `map` and `filter`. Non-stream-compatible operations are not supported and should be done after evaluation.
```python
from lazystream import LazyStream
stream = LazyStream.from_iterator(iter(range(10)))
stream.filter(lambda x: x % 2 == 0).map(lambda x: x * 2).evaluate()
# [0, 4, 8, 12, 16]
```
### Evaluation
You can obtain the results of a stream as a list via `evaluate`, which allows you to optionally set a limit on the number of elements to evaluate. This is useful/required for infinite streams.
```python
from lazystream import LazyStream
stream = LazyStream.from_lambda(lambda: 1)
stream.evaluate(5)
# [1, 1, 1, 1, 1]
```
You can also use the stream as an iterator itself. Note that proper termination conditions must be set for infinite streams.
```python
import random
from lazystream import LazyStream
# Iterate on a finite stream
finite_stream = LazyStream.from_iterator(iter(range(10)))
for x in finite_stream:
print(x)
# Iterate on an infinite stream
infinite_stream = LazyStream.from_lambda(lambda: random.randint(0, 1))
for x in infinite_stream:
print(x)
if x == 1:
break
```
In addition, the `reduce` operation is supported, which allows you to obtain a single value from a stream.
```python
from lazystream import LazyStream
# Reduce on a finite stream
stream = LazyStream.from_iterator(iter(range(10)))
stream.reduce(lambda x, y: x + y, accum=0)
# 45
# Reduce on an infinite stream
stream = LazyStream.from_lambda(lambda: 1)
stream.reduce(lambda x, y: x + y, accum=0, limit=5)
# 5
```
### Parallelism
You can add parallelism to the stream via functional mapping `par_map` and via results evaluation `par_evaluate`. Due to Python's parallelism implementation, this is only useful if your mapping function is IO-bound.
Note that Lazy Stream does not check for thread safety.
```python
from concurrent.futures import ThreadPoolExecutor
from lazystream import LazyStream
def io_bound_function(x):
# Do some IO-bound operation
return x
stream = LazyStream.from_iterator(iter(range(10)))
stream.par_map(
io_bound_function, executor=ThreadPoolExecutor(4)
).evaluate()
```
Raw data
{
"_id": null,
"home_page": "https://github.com/FizzyAgent/lazystream",
"name": "lazystream",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.7,<4.0",
"maintainer_email": "",
"keywords": "stream,lazy,functional",
"author": "Tan Pinxi",
"author_email": "tpinxi@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/ae/56/61b1eb0d14234dfe0394ac31784b777f0364dd1ff9deaf907dddfec26155/lazystream-0.1.6.tar.gz",
"platform": null,
"description": "# Lazy Stream\n\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)\n\nLazy Stream is a library for lazy evaluation in Python, inspired by the Scala Stream class.\n\nLazy Stream allows you to store and chain operations on a finite or infinite sequence of values. The final result will only be computed when needed, for better memory and performance over conventional Python lists.\n\n## Installation\n\nLazy Stream can be installed via pip:\n\n```bash\npip install lazystream\n```\n\n## Usage\n\nLazy Stream supports basic stream operations and parallelism. Below is a quick overview of the current features. Feel free to request additional features.\n\n### Creation\n\nLazy Stream is very easy to use. You can create a stream from any function or iterator and obtain the results via `evaluate`. Finite and infinite streams are supported, but care must be taken when using infinite streams to avoid infinite operation.\n\n```python\nfrom lazystream import LazyStream\n\n# Finite stream from iterator\nincremental_stream = LazyStream.from_iterator(iter(range(5)))\nincremental_stream.evaluate()\n# [0, 1, 2, 3, 4]\n\ndef fibonacci():\n a, b = 0, 1\n while True:\n yield a\n a, b = b, a + b\n \n# Infinite stream from function-defined iterator\nfibo_stream = LazyStream.from_iterator(fibonacci())\nfibo_stream.evaluate(5)\n# [0, 1, 1, 2, 3]\nfibo_stream.evaluate()\n# Unsafe, will never terminate\n```\n\nYou can also create a stream from a function, which will be evaluated lazily:\n\n```python\nimport random\nfrom lazystream import LazyStream\n\n# Infinite streams from function\nrandom_stream = LazyStream.from_lambda(lambda: random.randint(0, 100))\n```\n\n### Operations\n\nYou can chain operations on streams, which will be evaluated lazily. Classic stream-compatible operations are supported, such as `map` and `filter`. Non-stream-compatible operations are not supported and should be done after evaluation.\n\n```python\nfrom lazystream import LazyStream\n\nstream = LazyStream.from_iterator(iter(range(10)))\nstream.filter(lambda x: x % 2 == 0).map(lambda x: x * 2).evaluate()\n# [0, 4, 8, 12, 16]\n```\n\n### Evaluation\n\nYou can obtain the results of a stream as a list via `evaluate`, which allows you to optionally set a limit on the number of elements to evaluate. This is useful/required for infinite streams.\n\n```python\nfrom lazystream import LazyStream\n\nstream = LazyStream.from_lambda(lambda: 1)\nstream.evaluate(5)\n# [1, 1, 1, 1, 1]\n```\n\nYou can also use the stream as an iterator itself. Note that proper termination conditions must be set for infinite streams.\n\n```python\nimport random\nfrom lazystream import LazyStream\n\n# Iterate on a finite stream\nfinite_stream = LazyStream.from_iterator(iter(range(10)))\nfor x in finite_stream:\n print(x)\n\n# Iterate on an infinite stream\ninfinite_stream = LazyStream.from_lambda(lambda: random.randint(0, 1))\nfor x in infinite_stream:\n print(x)\n if x == 1:\n break\n```\n\nIn addition, the `reduce` operation is supported, which allows you to obtain a single value from a stream.\n\n```python\nfrom lazystream import LazyStream\n\n# Reduce on a finite stream\nstream = LazyStream.from_iterator(iter(range(10)))\nstream.reduce(lambda x, y: x + y, accum=0)\n# 45\n\n# Reduce on an infinite stream\nstream = LazyStream.from_lambda(lambda: 1)\nstream.reduce(lambda x, y: x + y, accum=0, limit=5)\n# 5\n```\n\n### Parallelism\n\nYou can add parallelism to the stream via functional mapping `par_map` and via results evaluation `par_evaluate`. Due to Python's parallelism implementation, this is only useful if your mapping function is IO-bound.\n\nNote that Lazy Stream does not check for thread safety.\n\n```python\nfrom concurrent.futures import ThreadPoolExecutor\nfrom lazystream import LazyStream\n\ndef io_bound_function(x):\n # Do some IO-bound operation\n return x\n\nstream = LazyStream.from_iterator(iter(range(10)))\nstream.par_map(\n io_bound_function, executor=ThreadPoolExecutor(4)\n).evaluate()\n```\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Scala-inspired stream for lazy evaluation",
"version": "0.1.6",
"project_urls": {
"Homepage": "https://github.com/FizzyAgent/lazystream",
"Repository": "https://github.com/FizzyAgent/lazystream"
},
"split_keywords": [
"stream",
"lazy",
"functional"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "5504be037d3b003ebff8cef1d3b3aeacf3a0702c74e5fd7cb85f17668fdefc9c",
"md5": "c9739beaeef972ae720e63d8b37e7784",
"sha256": "49103951dd6308e8ab80bcbfc657ddd5b871a685ec1d531a5851a0bb6062eff6"
},
"downloads": -1,
"filename": "lazystream-0.1.6-py3-none-any.whl",
"has_sig": false,
"md5_digest": "c9739beaeef972ae720e63d8b37e7784",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7,<4.0",
"size": 5274,
"upload_time": "2024-02-02T13:31:51",
"upload_time_iso_8601": "2024-02-02T13:31:51.527571Z",
"url": "https://files.pythonhosted.org/packages/55/04/be037d3b003ebff8cef1d3b3aeacf3a0702c74e5fd7cb85f17668fdefc9c/lazystream-0.1.6-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "ae5661b1eb0d14234dfe0394ac31784b777f0364dd1ff9deaf907dddfec26155",
"md5": "9fdbc6f75bb05fcdd55428b119483e59",
"sha256": "f55f8af30254022d9e000008b36c2260bc5b3eb2f1fb1d6cb49181028a12a965"
},
"downloads": -1,
"filename": "lazystream-0.1.6.tar.gz",
"has_sig": false,
"md5_digest": "9fdbc6f75bb05fcdd55428b119483e59",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7,<4.0",
"size": 4728,
"upload_time": "2024-02-02T13:31:53",
"upload_time_iso_8601": "2024-02-02T13:31:53.071717Z",
"url": "https://files.pythonhosted.org/packages/ae/56/61b1eb0d14234dfe0394ac31784b777f0364dd1ff9deaf907dddfec26155/lazystream-0.1.6.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-02-02 13:31:53",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "FizzyAgent",
"github_project": "lazystream",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "mypy",
"specs": [
[
"==",
"1.7.1"
]
]
},
{
"name": "pre-commit",
"specs": [
[
"~=",
"3.5.0"
]
]
},
{
"name": "pytest",
"specs": [
[
"~=",
"7.0.1"
]
]
}
],
"lcname": "lazystream"
}