{"id":16533064,"url":"https://github.com/remykarem/pyterator","last_synced_at":"2025-07-01T01:34:32.078Z","repository":{"id":99023300,"uuid":"427582650","full_name":"remykarem/pyterator","owner":"remykarem","description":"Pyterator helps you write fluent interfaces for collections","archived":false,"fork":false,"pushed_at":"2022-08-03T13:13:01.000Z","size":27,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-10T17:02:50.819Z","etag":null,"topics":["functional-programming","python"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/remykarem.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-11-13T05:59:38.000Z","updated_at":"2024-09-20T21:53:18.000Z","dependencies_parsed_at":"2023-06-29T19:46:10.448Z","dependency_job_id":null,"html_url":"https://github.com/remykarem/pyterator","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/remykarem/pyterator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remykarem%2Fpyterator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remykarem%2Fpyterator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remykarem%2Fpyterator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remykarem%2Fpyterator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/remykarem","download_url":"https://codeload.github.com/remykarem/pyterator/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remykarem%2Fpyterator/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262879429,"owners_count":23378621,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["functional-programming","python"],"created_at":"2024-10-11T18:14:02.759Z","updated_at":"2025-07-01T01:34:32.067Z","avatar_url":"https://github.com/remykarem.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pyterator\n\nWrite fluent functional programming idioms in Python.\n\n- Chain operations like `map`, `reduce`, `filter_map`\n- Lazy evaluation\n\nReadable transformation functions, as opposed to Lisp-ish prefix notation-esque map filter functions.\n\n---\n\n## Contents\n\n- [Installation](#installation)\n- [Quick start](#quick-start)\n- [How it works](#how-it-works)\n- [Motivation](#motivation)\n- [Design](#design)\n- [How is it different?](#how-it-works)\n- [Who is this for (and not for)?](#anyone)\n- [Design](#design)\n- [Examples](#examples)\n\n## Installation\n\n```bash\npip install git+https://github.com/remykarem/pyterator.git#egg=pyterator\n```\n\n## Quick start\n\n```python\n\u003e\u003e\u003e from pyterate import iterate\n```\n\n```python\n\u003e\u003e\u003e text = [\"hello\", \"world\"]\n\u003e\u003e\u003e iterate(text).map(str.upper).to_list()\n['HELLO', 'WORLD']\n```\n\nChain operations\n\n```python\n\u003e\u003e\u003e text = [\"hello\", \"my\", \"love\"]\n\u003e\u003e\u003e (\n...     iterate(text)\n...     .filterfalse(lambda x: x in [\"a\", \"my\"])\n...     .map(str.upper)\n...     .map(lambda x: x+\"!\")\n...     .to_list()\n... )\n['HELLO!', 'LOVE!']\n```\n\n## Motivation\n\nUsing `map`, `reduce` in Python forces you to write in prefix notation-esque which makes it hard to read.\n\nFor a transformation pipeline:\n\n```python\n[1, 2, 3, 4] -\u003e [2, 3, 4, 5] -\u003e [3, 5] -\u003e 15\n```\n\nPython:\n\n```python\nreduce(lambda x,y: x * y,\n    filter(lambda x: x % 2,\n        map(lambda x: x+1, [1, 2, 3, 4])), 1)\n```\n\nwhich looks similar to Common Lisp\n\n```lisp\n(reduce #'*\n    (remove-if #'evenp\n        (mapcar (lambda (x) (1+ x)) '(1 2 3 4))))\n```\n\nand Haskell\n\n```haskell\nfoldl (*) 1 \n    (filter odd \n        (map (\\x -\u003e x+1) [1, 2, 3, 4]))\n```\n\nwhich are languages where prefix notation is their natural syntax.\n\nList comprehensions, while idiomatic and commonplace among  developers, can be hard to read at times.\n\n## Design\n\nThis design is largely influenced by modern languages that implement functional programming idioms like Rust, Kotlin, Scala and JavaScript. The Apache Spark framework, which is written in Scala, largely exposes functional programming idioms in the Python APIs.\n\nWe want the subject of the chain of transformations to be the data itself, then call the operations in succession:\n\n```python\n(\n    [1,2,3,4]\n    .map(...)\n    .filter(...)\n    .reduce(...)\n)\n```\n\nand\n\n```python\n(\n    iter([1,2,3,4])\n    .map(...)\n    .filter(...)\n    .reduce(...)\n)\n```\n\nSince Python's iterator does not have methods `map`, `reduce`, we implemented our own `iterate`, which is similar to Python's builtin `iter`, so that client code can easily switch it out.\n\n```python\n(\n    iterate([1,2,3,4])\n    .map(...)\n    .filter(...)\n    .reduce(...)\n)\n```\n\niterator,\n\nIt is also a builder function, which returns a `_Pyterator` instance that implements `__next__`.\n\n## How it works\n\nLazy. Reduce operations and to_list() operations will 'materialise' your transformations.\n\n## Examples\n\n### Example 1: Square\n\n```txt\n[1, 2, 3, 4] -\u003e [1, 4, 9, 16]\n```\n\n```python\n\u003e\u003e\u003e from pyterator import iterate\n\u003e\u003e\u003e nums = [1, 2, 3, 4]\n```\n\nPyterator\n\n```python\n\u003e\u003e\u003e iterate(nums).map(lambda x: x**2).to_list()\n```\n\nList comprehension\n\n```python\n\u003e\u003e\u003e [x**2 for x in nums]\n```\n\nMap reduce\n\n```python\n\u003e\u003e\u003e list(map(lambda x: x**2, iter(nums)))\n```\n\n### Example 2: Filter\n\nPyterator\n\n```python\n\u003e\u003e\u003e iterate(nums).filter(lambda x: x \u003e 3).to_list()\n```\n\nList comprehension\n\n```python\n\u003e\u003e\u003e [x for x in nums if x \u003e 3]\n```\n\n### Flat map\n\n```python\n[\n\"peter piper\",\n\"picked a peck\",     -\u003e\n\"of pickled pepper\",\n]\n```\n\nList comprehension\n\n```python\n\u003e\u003e\u003e [word for text in texts for word in text.split()]\n```\n\nPyterator\n\n```python\n\u003e\u003e\u003e iterate(texts).flat_map(str.split).to_list()\n```\n\n### Multiple transformations\n\n```python\n\u003e\u003e\u003e from pyterator import iterate\n\u003e\u003e\u003e stopwords = {\"of\", \"a\"}\n\u003e\u003e\u003e texts = [\n    \"peter piper Picked a peck  \",\n    \"of Pickled pePper\",\n    \"\\na peck of pickled pepper peter piper picked\",\n]\n```\n\nList comprehension\n\n```python\n\u003e\u003e\u003e words = [\n        word for text in texts\n        for word in text.lower().strip().split()\n        if word not in stopwords]\n\u003e\u003e\u003e set(words)\n{'peck', 'pepper', 'peter', 'picked', 'pickled', 'piper'}\n```\n\nPyterator\n\n```python\n\u003e\u003e\u003e (\n...     iterate(texts)\n...     .map(str.strip)\n...     .map(str.lower)\n...     .flat_map(str.split)\n...     .filter(lambda word: word not in stopwords)\n...     .to_set()\n... )\n{'peck', 'pepper', 'peter', 'picked', 'pickled', 'piper'}\n```\n\n## Inspired by\n\nhttps://doc.rust-lang.org/std/iter/trait.Iterator.html\n\n## Gotchas\n\nThese gotchas pertain to mutability of the collections\n\n## What this is not for\n\nVectorised operations - use NumPy or other equivalent\n\n## API\n\ncommon\n\n- `map`\n- `enumerate`\n- `filter`\n- `for_each`\n- `filterfalse`\n- `filter_map`\n- `starmap`\n- `starfilter`\n- `star_map_filter`\n\norder\n\n- `reverse`\n\ndimension change\n\n- `partition`\n- `flat_map`\n- `star_flat_map`\n- `chunked`\n- `flatten`\n- `zip`\n- `chain`\n\npositional\n\n- `skip`\n- `first`\n- `nth`\n- `take`\n\ncollect\n\n- `to_list`\n- `to_set`\n- `to_dict`\n- `groupby`\n\nreduce\n\n- `reduce`\n- `all`\n- `any`\n- `min`\n- `max`\n- `sum`\n- `prod`\n- `join`\n- `sample`\n\n## Similar libraries\n\nNote that these libraries focus on fluent method chaining.\n\n- [PyFunctional](https://github.com/EntilZha/PyFunctional)\n- [fluent](https://github.com/dwt/fluent)\n- [Simple Smart Pipe](https://github.com/sspipe/sspipe)\n- [pyxtension](https://github.com/asuiu/pyxtension)\n- [pyiter](https://github.com/mokeyish/pyiter)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremykarem%2Fpyterator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fremykarem%2Fpyterator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremykarem%2Fpyterator/lists"}