streams.py


Namestreams.py JSON
Version 0.1.3 PyPI version JSON
download
home_pagehttps://github.com/PickwickSoft/pystreamapi
SummaryA stream library for Python inspired by Java Stream API
upload_time2022-12-06 16:07:44
maintainer
docs_urlNone
authorStefan Garlonta
requires_python
licenseGPL-3.0 license
keywords streams parallel data
VCS
bugtrack_url
requirements optional.py joblib parameterized
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Python Stream API

[![DeepSource](https://deepsource.io/gh/PickwickSoft/pystreamapi.svg/?label=active+issues&show_trend=true&token=7lV9pH1U-N1oId03M-XKZL5B)](https://deepsource.io/gh/PickwickSoft/pystreamapi/?ref=repository-badge)
[![Tests](https://github.com/PickwickSoft/pystreamapi/actions/workflows/unittests.yml/badge.svg)](https://github.com/PickwickSoft/pystreamapi/actions/workflows/unittests.yml)
[![Pylint](https://github.com/PickwickSoft/pystreamapi/actions/workflows/pylint.yml/badge.svg)](https://github.com/PickwickSoft/pystreamapi/actions/workflows/pylint.yml)

PyStreamAPI is a stream library for Python inspired by the Java Stream API and implements almost exact the same method names and functionality as Java Stream API!

PyStreamAPI uses lazy execution and offers sequential as well as parallel streams.

***Now you might think: Why another library? There are so many!***

Here are a few of the advantages this implementation has:

- Sequential as well as parallel version

- Lazy execution

- High speed

- 100% test coverage

- Pythonic implementation

- Clean and easy to read code

**Here a small example:**

```python
from pystreamapi import Stream

Stream.parallel_of([" ", '3', None, "2", 1, ""]) \
    .filter(lambda x: x is not None) \
    .map(str) \
    .map(lambda x: x.strip()) \
    .filter(lambda x: len(x) > 0) \
    .map(int) \
    .sorted() \
    .for_each(print) # Output: 1 2 3
```

The same code in Java:

```java
Object[] words = { " ", '3', null, "2", 1, "" };
Arrays.stream( words )
      .filter( Objects::nonNull )
      .map( Objects::toString )
      .map( String::trim )
      .filter( s -> ! s.isEmpty() )
      .map( Integer::parseInt )
      .sorted()
      .forEach( System.out::println );  // Output: 1 2 3
```

## What is a Stream?

A stream is a pipeline, in which elements from an Iterable are computed on demand.
It is similar to SQL queries and is used to manipulate data. 

E.g. Get the second-highest salary of Employee

```sql
Select distinct Salary from Employee e1 
where 2=Select count(distinct Salary) 
from Employee e2 where e1.salary<=e2.salary;
```

Now the same thing in Python

```python
employees = [...] # A list with employee objects
Stream.of(employees) \
    .map(lambda x: x.salary) \
    .sorted() \
    .reversed() \
    .to_list()[1] # Returns the second-highest salary
```

`pystreamapi.Stream` represents a stream on which one or more operations can be performed. Stream operations are either intermediate or terminal.

The terminal operations return a result of a specific type, and intermediate operations return the stream itself, so we can chain multiple methods together to perform the operation in multiple steps.

*Again the example from above:*

```python
Stream.of(employees) \ # Create a BaseStream object
    .map(lambda x: x.salary) \ # Intermediate Operation
    .sorted() \ # Intermediate Operation
    .reversed() \ # Intermediate Operation
    .to_list()[1] # Terminal Operation
```

Operations can be performed on a stream in parallel or sequentially. When parallel, it is called parallel stream else it is a sequential stream.

Based on the above points, a stream is:

- Not a data structure
- Not offering indexed access
- Designed for lambdas
- Easy to aggregate as lists or tuples/sets
- Parallelizable
- Processing lazy

## Get started: Installation

To start using PyStreamAPI just install the module with this command:

```bash
pip install streams.py  
```

Afterwards you can import it with:

```python
from pystreamapi import Stream
```

:tada: PyStreamAPI is now ready to process your data

## Build a new Stream

There are a few factory methods that create new Streams.

```python
Stream.of([1, 2, 3]) # Can return a sequential or a parallel stream
```

Using the `of()` method will let the implementation decide which `Stream` to use.

> **Note** 
> 
> Currently, it returns always a `SequentialStream`

---

```python
Stream.parallel_of([1, 2, 3]) # Returns a parallel stream
```

---

```python
Stream.sequential_of([1, 2, 3]) # Returns a sequential stream
```

---

```python
Stream.of_noneable([1, 2, 3]) # Can return a sequential or a parallel stream
```

If the source is `None`, you get an empty `Stream`

---

```python
Stream.iterate(0, lambda n: n + 2)
```

Creates a Stream of an infinite Iterator like 0, 2, 4, 6, 8, 10, 12, 14...

> **Note**
> Do not forget to limit the stream with `.limit()`

---

```python
Stream.concat(Stream.of([1, 2]), Stream.of([3, 4])) 
# Like Stream.of([1, 2, 3, 4])
```

Creates a new Stream from multiple Streams. Order doesn't change

## API Documentation

### Intermediate Operations

#### `filter()` : Restrict the Stream

Returns a stream consisting of the elements of this stream that match the given predicate.

```python
Stream.of([1, 2, 3, None]) \
    .filter(lambda x: x is not None) \
    .for_each(print) # 1 2 3
```

#### `map()` : Convert the elements in the Stream

Returns a stream consisting of the results of applying the given function to the elements of this stream.

```python
Stream.of([1, "2", 3.0, None]) \
    .map(str) \
    .to_list() # ["1", "2", "3.0", "None"]
```

#### `map_to_int()` : Convert the elements in the Stream to an Integer

Returns a stream consisting of the results of applying the `int()` function to the elements of this stream. Note that this method is not none safe.

```python
Stream.of([1, "2", 3.0]) \
    .map_to_int() \
    .to_list() # [1, 2, 3]
```

#### `map_to_str()` : Convert the elements in the Stream to a String

Returns a stream consisting of the results of applying the `str()` function to the elements of this stream.

```python
Stream.of([1, 2, 3]) \
    .map_to_str() \
    .to_list() # ["1", "2", "3"]
```

#### `flat_map()` : Streams in Streams

Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.

```python
Stream.of([1, 2, 3]) \
    .flat_map(lambda x: self.stream([x, x])) \
    .to_list() # [1, 1, 2, 2, 3, 3]
```

#### `distinct()` : Remove duplicates

Returns a stream consisting of the distinct elements of this stream.

```python
Stream.of([1, 1, 2, 3]) \
    .distinct() \
    .to_list() # [1, 2, 3]
```

#### `sorted()` : Sort Stream

Returns a stream consisting of the elements of this stream, sorted according to natural order or comparator.

```python
Stream.of([2, 9, 1])
    .sorted()
    .to_list()  # [1, 2, 9]
```

Here is an example with a custom comparator:

```python
Stream.of(["a", "cc", "bbb"])
    .sorted(lambda x, y: len(y) - len(x))
    .to_list()  # ['bbb', 'cc', 'a']
```

#### `reversed()` : Reverse Stream

Returns a stream consisting of the elements of this stream in reverse order.

```python
Stream.of([1, 2, 3])
    .reversed()
    .to_list()  # [3, 2, 1]
```

#### `peek()` : View intermediate results

Returns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream.

```python
Stream.of([2, 1, 3]) \
    .sorted() \
    .peek(print) \ # 1, 2, 3
    .reversed() \
    .for_each(print) # 3, 2, 1
```

#### `limit()` : Limit the Stream to a certain number of elements

Returns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.

```python
Stream.of([1, 2, 3]) \
    .limit(2) \
    .to_list() # [1, 2]
```

#### `skip()` : Skip the first n elements of the Stream

Returns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream.

```python
Stream.of([1, 2, 3]) \
    .skip(2) \
    .to_list() # [3]
```

#### `take_while()` : Take elements while the predicate is true

Returns, if this stream is ordered, a stream consisting of the longest prefix of elements taken from this stream that match the given predicate.

```python
Stream.of([1, 2, 3]) \
    .take_while(lambda x: x < 3) \
    .to_list() # [1, 2]
```

#### `drop_while()` : Drop elements while the predicate is true

Returns, if this stream is ordered, a stream consisting of the remaining elements of this stream after dropping the longest prefix of elements that match the given predicate.

```python
Stream.of([1, 2, 3]) \
    .drop_while(lambda x: x < 3) \
    .to_list() # [3]
```

### Terminal Operations

These operations will trigger the pipeline's execution

#### `all_match()` : Check if all elements match a predicate

Returns whether all elements of this stream match the provided predicate.

```python
Stream.of([1, 2, 3]) \
    .all_match(lambda x: x > 0) # True
```

#### `any_match()` : Check if any element matches a predicate

Returns whether any elements of this stream match the provided predicate.

```python
Stream.of([1, 2, 3]) \
    .any_match(lambda x: x < 0) # False
```

#### `none_match()` : Check if no element matches a predicate

Returns whether no elements of this stream match the provided predicate.

```python
Stream.of([1, 2, 3]) \
    .none_match(lambda x: x < 0) # True
```

#### `count()` : Count the number of elements in the Stream

Returns the number of elements in this stream.

```python
Stream.of([1, 2, 3]) \
    .count() # 3
```

#### `min()` : Find the minimum element in the Stream

Returns the minimum element of this stream

```python
Stream.of([1, 2, 3]) \
    .min() # 1
```

#### `max()` : Find the maximum element in the Stream

Returns the maximum element of this stream

```python
Stream.of([1, 2, 3]) \
    .max() # 3
```

#### `reduce()` : Reduce the Stream to a single value

Returns the result of reducing the elements of this stream to a single value using the provided reducer.

```python
Stream.of([1, 2, 3]) \
    .reduce(lambda x, y: x + y) # 6
```

#### `for_each()` : Perform an action for each element in the Stream

Performs the provided action for each element of this stream.

```python
Stream.of([1, 2, 3]) \
    .for_each(print) # 1 2 3
```

#### `to_list()` : Convert the Stream to a List

Returns a list containing the elements of this stream.

```python
Stream.of([1, 2, 3]) \
    .to_list() # [1, 2, 3]
```

#### `to_set()` : Convert the Stream to a Set

Returns a set containing the elements of this stream.

```python
Stream.of([1, 2, 3]) \
    .to_set() # {1, 2, 3}
```

#### `to_tuple()` : Convert the Stream to a Tuple

Returns a tuple containing the elements of this stream.

```python
Stream.of([1, 2, 3]) \
    .to_tuple() # (1, 2, 3)
```

#### `find_first()` : Find the first element in the Stream

Returns an Optional describing the first element of this stream, or an empty Optional if the stream is empty.

```python
Stream.of([1, 2, 3]) \
    .find_first() # Optional[1]
```

#### `find_any()` : Find an element in the Stream

Returns an Optional describing an arbitrary element of this stream, or an empty Optional if the stream is empty.

```python
Stream.of([1, 2, 3]) \
    .find_any() # Optional[1]
```

## Complex Examples

#### Get all numbers from list of different types. Use parallelization.

```python
Stream.parallel_of([" ", '3', None, "2", 1, ""]) \
    .filter(lambda x: x is not None) \
    .map(str) \
    .map(lambda x: x.strip()) \
    .filter(lambda x: len(x) > 0) \
    .map(int) \
    .sorted()\
    .for_each(print) # 1 2 3
```

#### Generate a Stream of 10 Fibonacci numbers

```python
def fib():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

Stream.of(fib()) \
    .limit(10) \
    .for_each(print) # 0 1 1 2 3 5 8 13 21 34
```

## Performance

Note that parallel Streams are not always faster than sequential Streams. Especially when the number of elements is small, we can expect sequential Streams to be faster.

## Bug Reports

Bug reports can be submitted in GitHub's [issue tracker](https://github.com/PickwickSoft/pystreamapi/issues).

## Contributing

Contributions are welcome! Please submit a pull request or open an issue.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/PickwickSoft/pystreamapi",
    "name": "streams.py",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "streams,parallel,data",
    "author": "Stefan Garlonta",
    "author_email": "stefan@pickwicksoft.org",
    "download_url": "https://files.pythonhosted.org/packages/15/0a/fe79231d3a79fdc689c759882eea66c91dcea2447953a7f7808fe60b5779/streams.py-0.1.3.tar.gz",
    "platform": null,
    "description": "# Python Stream API\n\n[![DeepSource](https://deepsource.io/gh/PickwickSoft/pystreamapi.svg/?label=active+issues&show_trend=true&token=7lV9pH1U-N1oId03M-XKZL5B)](https://deepsource.io/gh/PickwickSoft/pystreamapi/?ref=repository-badge)\n[![Tests](https://github.com/PickwickSoft/pystreamapi/actions/workflows/unittests.yml/badge.svg)](https://github.com/PickwickSoft/pystreamapi/actions/workflows/unittests.yml)\n[![Pylint](https://github.com/PickwickSoft/pystreamapi/actions/workflows/pylint.yml/badge.svg)](https://github.com/PickwickSoft/pystreamapi/actions/workflows/pylint.yml)\n\nPyStreamAPI is a stream library for Python inspired by the Java Stream API and implements almost exact the same method names and functionality as Java Stream API!\n\nPyStreamAPI uses lazy execution and offers sequential as well as parallel streams.\n\n***Now you might think: Why another library? There are so many!***\n\nHere are a few of the advantages this implementation has:\n\n- Sequential as well as parallel version\n\n- Lazy execution\n\n- High speed\n\n- 100% test coverage\n\n- Pythonic implementation\n\n- Clean and easy to read code\n\n**Here a small example:**\n\n```python\nfrom pystreamapi import Stream\n\nStream.parallel_of([\" \", '3', None, \"2\", 1, \"\"]) \\\n    .filter(lambda x: x is not None) \\\n    .map(str) \\\n    .map(lambda x: x.strip()) \\\n    .filter(lambda x: len(x) > 0) \\\n    .map(int) \\\n    .sorted() \\\n    .for_each(print) # Output: 1 2 3\n```\n\nThe same code in Java:\n\n```java\nObject[] words = { \" \", '3', null, \"2\", 1, \"\" };\nArrays.stream( words )\n      .filter( Objects::nonNull )\n      .map( Objects::toString )\n      .map( String::trim )\n      .filter( s -> ! s.isEmpty() )\n      .map( Integer::parseInt )\n      .sorted()\n      .forEach( System.out::println );  // Output: 1 2 3\n```\n\n## What is a Stream?\n\nA stream is a pipeline, in which elements from an Iterable are computed on demand.\nIt is similar to SQL queries and is used to manipulate data. \n\nE.g. Get the second-highest salary of Employee\n\n```sql\nSelect distinct Salary from Employee e1 \nwhere 2=Select count(distinct Salary) \nfrom Employee e2 where e1.salary<=e2.salary;\n```\n\nNow the same thing in Python\n\n```python\nemployees = [...] # A list with employee objects\nStream.of(employees) \\\n    .map(lambda x: x.salary) \\\n    .sorted() \\\n    .reversed() \\\n    .to_list()[1] # Returns the second-highest salary\n```\n\n`pystreamapi.Stream` represents a stream on which one or more operations can be performed. Stream operations are either intermediate or terminal.\n\nThe terminal operations return a result of a specific type, and intermediate operations return the stream itself, so we can chain multiple methods together to perform the operation in multiple steps.\n\n*Again the example from above:*\n\n```python\nStream.of(employees) \\ # Create a BaseStream object\n    .map(lambda x: x.salary) \\ # Intermediate Operation\n    .sorted() \\ # Intermediate Operation\n    .reversed() \\ # Intermediate Operation\n    .to_list()[1] # Terminal Operation\n```\n\nOperations can be performed on a stream in parallel or sequentially. When parallel, it is called parallel stream else it is a sequential stream.\n\nBased on the above points, a stream is:\n\n- Not a data structure\n- Not offering indexed access\n- Designed for lambdas\n- Easy to aggregate as lists or tuples/sets\n- Parallelizable\n- Processing lazy\n\n## Get started: Installation\n\nTo start using PyStreamAPI just install the module with this command:\n\n```bash\npip install streams.py  \n```\n\nAfterwards you can import it with:\n\n```python\nfrom pystreamapi import Stream\n```\n\n:tada: PyStreamAPI is now ready to process your data\n\n## Build a new Stream\n\nThere are a few factory methods that create new Streams.\n\n```python\nStream.of([1, 2, 3]) # Can return a sequential or a parallel stream\n```\n\nUsing the `of()` method will let the implementation decide which `Stream` to use.\n\n> **Note** \n> \n> Currently, it returns always a `SequentialStream`\n\n---\n\n```python\nStream.parallel_of([1, 2, 3]) # Returns a parallel stream\n```\n\n---\n\n```python\nStream.sequential_of([1, 2, 3]) # Returns a sequential stream\n```\n\n---\n\n```python\nStream.of_noneable([1, 2, 3]) # Can return a sequential or a parallel stream\n```\n\nIf the source is `None`, you get an empty `Stream`\n\n---\n\n```python\nStream.iterate(0, lambda n: n + 2)\n```\n\nCreates a Stream of an infinite Iterator like 0, 2, 4, 6, 8, 10, 12, 14...\n\n> **Note**\n> Do not forget to limit the stream with `.limit()`\n\n---\n\n```python\nStream.concat(Stream.of([1, 2]), Stream.of([3, 4])) \n# Like Stream.of([1, 2, 3, 4])\n```\n\nCreates a new Stream from multiple Streams. Order doesn't change\n\n## API Documentation\n\n### Intermediate Operations\n\n#### `filter()` : Restrict the Stream\n\nReturns a stream consisting of the elements of this stream that match the given predicate.\n\n```python\nStream.of([1, 2, 3, None]) \\\n    .filter(lambda x: x is not None) \\\n    .for_each(print) # 1 2 3\n```\n\n#### `map()` : Convert the elements in the Stream\n\nReturns a stream consisting of the results of applying the given function to the elements of this stream.\n\n```python\nStream.of([1, \"2\", 3.0, None]) \\\n    .map(str) \\\n    .to_list() # [\"1\", \"2\", \"3.0\", \"None\"]\n```\n\n#### `map_to_int()` : Convert the elements in the Stream to an Integer\n\nReturns a stream consisting of the results of applying the `int()` function to the elements of this stream. Note that this method is not none safe.\n\n```python\nStream.of([1, \"2\", 3.0]) \\\n    .map_to_int() \\\n    .to_list() # [1, 2, 3]\n```\n\n#### `map_to_str()` : Convert the elements in the Stream to a String\n\nReturns a stream consisting of the results of applying the `str()` function to the elements of this stream.\n\n```python\nStream.of([1, 2, 3]) \\\n    .map_to_str() \\\n    .to_list() # [\"1\", \"2\", \"3\"]\n```\n\n#### `flat_map()` : Streams in Streams\n\nReturns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.\n\n```python\nStream.of([1, 2, 3]) \\\n    .flat_map(lambda x: self.stream([x, x])) \\\n    .to_list() # [1, 1, 2, 2, 3, 3]\n```\n\n#### `distinct()` : Remove duplicates\n\nReturns a stream consisting of the distinct elements of this stream.\n\n```python\nStream.of([1, 1, 2, 3]) \\\n    .distinct() \\\n    .to_list() # [1, 2, 3]\n```\n\n#### `sorted()` : Sort Stream\n\nReturns a stream consisting of the elements of this stream, sorted according to natural order or comparator.\n\n```python\nStream.of([2, 9, 1])\n    .sorted()\n    .to_list()  # [1, 2, 9]\n```\n\nHere is an example with a custom comparator:\n\n```python\nStream.of([\"a\", \"cc\", \"bbb\"])\n    .sorted(lambda x, y: len(y) - len(x))\n    .to_list()  # ['bbb', 'cc', 'a']\n```\n\n#### `reversed()` : Reverse Stream\n\nReturns a stream consisting of the elements of this stream in reverse order.\n\n```python\nStream.of([1, 2, 3])\n    .reversed()\n    .to_list()  # [3, 2, 1]\n```\n\n#### `peek()` : View intermediate results\n\nReturns a stream consisting of the elements of this stream, additionally performing the provided action on each element as elements are consumed from the resulting stream.\n\n```python\nStream.of([2, 1, 3]) \\\n    .sorted() \\\n    .peek(print) \\ # 1, 2, 3\n    .reversed() \\\n    .for_each(print) # 3, 2, 1\n```\n\n#### `limit()` : Limit the Stream to a certain number of elements\n\nReturns a stream consisting of the elements of this stream, truncated to be no longer than maxSize in length.\n\n```python\nStream.of([1, 2, 3]) \\\n    .limit(2) \\\n    .to_list() # [1, 2]\n```\n\n#### `skip()` : Skip the first n elements of the Stream\n\nReturns a stream consisting of the remaining elements of this stream after discarding the first n elements of the stream.\n\n```python\nStream.of([1, 2, 3]) \\\n    .skip(2) \\\n    .to_list() # [3]\n```\n\n#### `take_while()` : Take elements while the predicate is true\n\nReturns, if this stream is ordered, a stream consisting of the longest prefix of elements taken from this stream that match the given predicate.\n\n```python\nStream.of([1, 2, 3]) \\\n    .take_while(lambda x: x < 3) \\\n    .to_list() # [1, 2]\n```\n\n#### `drop_while()` : Drop elements while the predicate is true\n\nReturns, if this stream is ordered, a stream consisting of the remaining elements of this stream after dropping the longest prefix of elements that match the given predicate.\n\n```python\nStream.of([1, 2, 3]) \\\n    .drop_while(lambda x: x < 3) \\\n    .to_list() # [3]\n```\n\n### Terminal Operations\n\nThese operations will trigger the pipeline's execution\n\n#### `all_match()` : Check if all elements match a predicate\n\nReturns whether all elements of this stream match the provided predicate.\n\n```python\nStream.of([1, 2, 3]) \\\n    .all_match(lambda x: x > 0) # True\n```\n\n#### `any_match()` : Check if any element matches a predicate\n\nReturns whether any elements of this stream match the provided predicate.\n\n```python\nStream.of([1, 2, 3]) \\\n    .any_match(lambda x: x < 0) # False\n```\n\n#### `none_match()` : Check if no element matches a predicate\n\nReturns whether no elements of this stream match the provided predicate.\n\n```python\nStream.of([1, 2, 3]) \\\n    .none_match(lambda x: x < 0) # True\n```\n\n#### `count()` : Count the number of elements in the Stream\n\nReturns the number of elements in this stream.\n\n```python\nStream.of([1, 2, 3]) \\\n    .count() # 3\n```\n\n#### `min()` : Find the minimum element in the Stream\n\nReturns the minimum element of this stream\n\n```python\nStream.of([1, 2, 3]) \\\n    .min() # 1\n```\n\n#### `max()` : Find the maximum element in the Stream\n\nReturns the maximum element of this stream\n\n```python\nStream.of([1, 2, 3]) \\\n    .max() # 3\n```\n\n#### `reduce()` : Reduce the Stream to a single value\n\nReturns the result of reducing the elements of this stream to a single value using the provided reducer.\n\n```python\nStream.of([1, 2, 3]) \\\n    .reduce(lambda x, y: x + y) # 6\n```\n\n#### `for_each()` : Perform an action for each element in the Stream\n\nPerforms the provided action for each element of this stream.\n\n```python\nStream.of([1, 2, 3]) \\\n    .for_each(print) # 1 2 3\n```\n\n#### `to_list()` : Convert the Stream to a List\n\nReturns a list containing the elements of this stream.\n\n```python\nStream.of([1, 2, 3]) \\\n    .to_list() # [1, 2, 3]\n```\n\n#### `to_set()` : Convert the Stream to a Set\n\nReturns a set containing the elements of this stream.\n\n```python\nStream.of([1, 2, 3]) \\\n    .to_set() # {1, 2, 3}\n```\n\n#### `to_tuple()` : Convert the Stream to a Tuple\n\nReturns a tuple containing the elements of this stream.\n\n```python\nStream.of([1, 2, 3]) \\\n    .to_tuple() # (1, 2, 3)\n```\n\n#### `find_first()` : Find the first element in the Stream\n\nReturns an Optional describing the first element of this stream, or an empty Optional if the stream is empty.\n\n```python\nStream.of([1, 2, 3]) \\\n    .find_first() # Optional[1]\n```\n\n#### `find_any()` : Find an element in the Stream\n\nReturns an Optional describing an arbitrary element of this stream, or an empty Optional if the stream is empty.\n\n```python\nStream.of([1, 2, 3]) \\\n    .find_any() # Optional[1]\n```\n\n## Complex Examples\n\n#### Get all numbers from list of different types. Use parallelization.\n\n```python\nStream.parallel_of([\" \", '3', None, \"2\", 1, \"\"]) \\\n    .filter(lambda x: x is not None) \\\n    .map(str) \\\n    .map(lambda x: x.strip()) \\\n    .filter(lambda x: len(x) > 0) \\\n    .map(int) \\\n    .sorted()\\\n    .for_each(print) # 1 2 3\n```\n\n#### Generate a Stream of 10 Fibonacci numbers\n\n```python\ndef fib():\n    a, b = 0, 1\n    while True:\n        yield a\n        a, b = b, a + b\n\nStream.of(fib()) \\\n    .limit(10) \\\n    .for_each(print) # 0 1 1 2 3 5 8 13 21 34\n```\n\n## Performance\n\nNote that parallel Streams are not always faster than sequential Streams. Especially when the number of elements is small, we can expect sequential Streams to be faster.\n\n## Bug Reports\n\nBug reports can be submitted in GitHub's [issue tracker](https://github.com/PickwickSoft/pystreamapi/issues).\n\n## Contributing\n\nContributions are welcome! Please submit a pull request or open an issue.\n",
    "bugtrack_url": null,
    "license": "GPL-3.0 license",
    "summary": "A stream library for Python inspired by Java Stream API",
    "version": "0.1.3",
    "split_keywords": [
        "streams",
        "parallel",
        "data"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "b7e4674bc90487c494962a757f2ab138",
                "sha256": "edfe179d1347dceb28eb097955dfc6ad2be13c3f565fb76ffd1e6510115b6795"
            },
            "downloads": -1,
            "filename": "streams.py-0.1.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b7e4674bc90487c494962a757f2ab138",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 24663,
            "upload_time": "2022-12-06T16:07:42",
            "upload_time_iso_8601": "2022-12-06T16:07:42.939292Z",
            "url": "https://files.pythonhosted.org/packages/a4/11/04c9fc7a48ab0a129ed69abc28b1485f0d0bfaba4ace1e0adfd0798a7ea4/streams.py-0.1.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "2faa3c06039327681794fda5863a7473",
                "sha256": "607ef704ceb7a8d0debeeecc910870c7b9a4abeb79231b55d80e7da33e921c86"
            },
            "downloads": -1,
            "filename": "streams.py-0.1.3.tar.gz",
            "has_sig": false,
            "md5_digest": "2faa3c06039327681794fda5863a7473",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 24835,
            "upload_time": "2022-12-06T16:07:44",
            "upload_time_iso_8601": "2022-12-06T16:07:44.621855Z",
            "url": "https://files.pythonhosted.org/packages/15/0a/fe79231d3a79fdc689c759882eea66c91dcea2447953a7f7808fe60b5779/streams.py-0.1.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2022-12-06 16:07:44",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "PickwickSoft",
    "github_project": "pystreamapi",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "optional.py",
            "specs": [
                [
                    "~=",
                    "1.3.2"
                ]
            ]
        },
        {
            "name": "joblib",
            "specs": [
                [
                    "~=",
                    "1.1.0"
                ]
            ]
        },
        {
            "name": "parameterized",
            "specs": [
                [
                    "~=",
                    "0.8.1"
                ]
            ]
        }
    ],
    "tox": true,
    "lcname": "streams.py"
}
        
Elapsed time: 0.04425s