{"id":21179555,"url":"https://github.com/klahap/kothon","last_synced_at":"2025-10-12T23:03:50.346Z","repository":{"id":223029072,"uuid":"758954500","full_name":"klahap/kothon","owner":"klahap","description":"Enhance Python with Kotlin's Sequence class and functional programming for efficient, expressive data pipelines.","archived":false,"fork":false,"pushed_at":"2024-06-23T11:11:38.000Z","size":55,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-09-14T22:42:08.486Z","etag":null,"topics":["data-processing","functional-programming","kotlin-sequences","lazy-evaluation","python","type-hints"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/klahap.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2024-02-17T15:09:25.000Z","updated_at":"2024-06-23T11:11:05.000Z","dependencies_parsed_at":null,"dependency_job_id":"84570634-37d7-4754-8e99-2cd560c6bbf7","html_url":"https://github.com/klahap/kothon","commit_stats":null,"previous_names":["klaush09/kothon","klahap/kothon"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/klahap/kothon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klahap%2Fkothon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klahap%2Fkothon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klahap%2Fkothon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klahap%2Fkothon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/klahap","download_url":"https://codeload.github.com/klahap/kothon/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/klahap%2Fkothon/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279013418,"owners_count":26085274,"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","status":"online","status_checked_at":"2025-10-12T02:00:06.719Z","response_time":53,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["data-processing","functional-programming","kotlin-sequences","lazy-evaluation","python","type-hints"],"created_at":"2024-11-20T17:32:15.054Z","updated_at":"2025-10-12T23:03:50.314Z","avatar_url":"https://github.com/klahap.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kothon\n\n![Python Version from PEP 621 TOML](https://img.shields.io/python/required-version-toml?tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fklahap%2Fkothon%2Fmain%2Fpyproject.toml)\n![GitHub License](https://img.shields.io/github/license/klahap/kothon)\n![PyPI - Status](https://img.shields.io/pypi/status/kothon)\n![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/klahap/kothon/tests.yml)\n![Static Badge](https://img.shields.io/badge/coverage-100%25-success)\n\n[//]: # (Using a static badge for 100% code coverage is justified because your test pipeline ensures coverage never falls below 100%, making dynamic updates unnecessary.)\n\nKothon is a Python library designed to bring the elegance and functionality of Kotlin's Sequence class into the Python\necosystem. With an emphasis on functional programming paradigms, Kothon enables Python developers to leverage\nlazy-evaluated sequences, allowing for efficient and expressive data processing pipelines.\n\n## Features\n\n- **Functional Programming**: Embrace functional programming with a rich set of operators\n  like `map`, `filter`, `reduce`, and much more, enabling you to write more declarative and concise code.\n- **Strongly Typed**: Leveraging Python's type hints for clearer, more robust code.\n- **Lazy Evaluation**: Kothon sequences are evaluated lazily, meaning computations are deferred until the value is\n  needed, enhancing performance especially for large datasets.\n- **Interoperability**: Seamlessly integrate with existing Python codebases, enjoying the benefits of Kotlin-like\n  sequences without disrupting your current workflow.\n- **Easy to Use**: Kothon's API is designed to be intuitive for both Python and Kotlin developers, ensuring a smooth\n  learning curve.\n\n## Installation\n\nTo install Kothon, simply run the following command in your terminal:\n\n```bash\npip install kothon\n```\n\n## Quick Start\n\nHere's a quick example to get you started with Kothon:\n\n```python\nfrom kothon import Seq\n\ninput_data = [0, 1, None, 2, 3, None, 4]\n\n# Apply some functional operations\nresult = Seq(input_data) \\\n    .filter_not_none() \\\n    .filter(lambda x: x % 2 == 0) \\\n    .map(lambda x: x * 2) \\\n    .to_list()\n\nprint(result)  # Output: [0, 4, 8]\n```\n\nAlternatively, utilize `pipe` for a more Pythonic approach.\n\n```python\nfrom kothon import pipe, filter_not_none, kothon_filter, kothon_map\n\ninput_data = [0, 1, None, 2, 3, None, 4]\n\n# Apply some functional operations\nresult = pipe(\n    input_data,\n    filter_not_none,\n    kothon_filter(lambda x: x % 2 == 0),\n    kothon_map(lambda x: x * 2),\n).to_list()\n\nprint(result)  # Output: [0, 4, 8]\n```\n\n## Existing functions in `Seq`\n\n- [filter](#filter)\n- [filter_not_none](#filter_not_none)\n- [filter_is_instance](#filter_is_instance)\n- [map](#map)\n- [map_not_none](#map_not_none)\n- [flat_map](#flat_map)\n- [flatten](#flatten)\n- [associate](#associate)\n- [associate_by](#associate_by)\n- [associate_with](#associate_with)\n- [group_by](#group_by)\n- [to_list](#to_list)\n- [to_set](#to_set)\n- [all](#all)\n- [none](#none)\n- [any](#any)\n- [max](#max)\n- [max_or_none](#max_or_none)\n- [max_by](#max_by)\n- [max_by_or_none](#max_by_or_none)\n- [min](#min)\n- [min_or_none](#min_or_none)\n- [min_by](#min_by)\n- [min_by_or_none](#min_by_or_none)\n- [single](#single)\n- [single_or_none](#single_or_none)\n- [first](#first)\n- [first_or_none](#first_or_none)\n- [last](#last)\n- [last_or_none](#last_or_none)\n- [drop](#drop)\n- [drop_while](#drop_while)\n- [take](#take)\n- [take_while](#take_while)\n- [sorted](#sorted)\n- [sorted_by](#sorted_by)\n- [sorted_desc](#sorted_desc)\n- [sorted_by_desc](#sorted_by_desc)\n- [chunked](#chunked)\n- [enumerate](#enumerate)\n- [shuffled](#shuffled)\n- [reduce](#reduce)\n- [reduce_or_none](#reduce_or_none)\n- [sum](#sum)\n- [sum_or_none](#sum_or_none)\n- [distinct](#distinct)\n- [distinct_by](#distinct_by)\n- [for_each](#for_each)\n- [join_to_string](#join_to_string)\n- [partition](#partition)\n\n### filter\n\nFilters elements based on a predicate.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 2, 3, 4, 5])\n\u003e\u003e\u003e seq.filter(lambda x: x % 2 == 0).to_list()\n[2, 4]\n\u003e\u003e\u003e\n```\n\n### filter_not_none\n\nFilters out `None` values from the sequence.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, None, 2, None, 3])\n\u003e\u003e\u003e seq.filter_not_none().to_list()\n[1, 2, 3]\n\u003e\u003e\u003e\n```\n\n### filter_is_instance\n\nFilters elements of the sequence based on their type.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 'two', 3, 'four', 5])\n\u003e\u003e\u003e seq.filter_is_instance(str).to_list()\n['two', 'four']\n\u003e\u003e\u003e\n```\n\n### map\n\nApplies a function to each element in the sequence.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 2, 3])\n\u003e\u003e\u003e seq.map(lambda x: x * x).to_list()\n[1, 4, 9]\n\u003e\u003e\u003e\n```\n\n### map_not_none\n\nApplies a function to each element and filters out `None` results.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 2, 3, 4])\n\u003e\u003e\u003e seq.map_not_none(lambda x: x * 2 if x % 2 == 0 else None).to_list()\n[4, 8]\n\u003e\u003e\u003e\n```\n\n### flat_map\n\nApplies a function to each element that returns an iterable and flattens the result.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 2, 3])\n\u003e\u003e\u003e seq.flat_map(lambda x: [x, -x]).to_list()\n[1, -1, 2, -2, 3, -3]\n\u003e\u003e\u003e\n```\n\n### flatten\n\nFlattens a sequence of iterables into a single sequence.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([[1, 2], [3, 4], [5]])\n\u003e\u003e\u003e seq.flatten().to_list()\n[1, 2, 3, 4, 5]\n\u003e\u003e\u003e\n```\n\n### associate\n\nTransforms elements into key-value pairs and aggregates them into a dictionary.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([\"a\", \"bb\", \"ccc\"])\n\u003e\u003e\u003e seq.associate(lambda x: (x, len(x)))\n{'a': 1, 'bb': 2, 'ccc': 3}\n\u003e\u003e\u003e\n```\n\n### associate_by\n\nCreates a dictionary from the sequence by determining keys using a specified key selector function.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([\"apple\", \"banana\", \"cherry\"])\n\u003e\u003e\u003e seq.associate_by(lambda x: x[0])\n{'a': 'apple', 'b': 'banana', 'c': 'cherry'}\n\u003e\u003e\u003e\n```\n\n### associate_with\n\nCreates a dictionary from the sequence with elements as keys and values determined by a value selector function.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 2, 3])\n\u003e\u003e\u003e seq.associate_with(lambda x: x * x)\n{1: 1, 2: 4, 3: 9}\n\u003e\u003e\u003e\n```\n\n### group_by\n\nGroups elements based on a key function.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([\"one\", \"two\", \"three\"])\n\u003e\u003e\u003e seq.group_by(len)\n{3: ['one', 'two'], 5: ['three']}\n\u003e\u003e\u003e\n```\n\n### to_list\n\nConverts the sequence to a list.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 2, 3])\n\u003e\u003e\u003e seq.to_list()\n[1, 2, 3]\n\u003e\u003e\u003e\n```\n\n### to_set\n\nConverts the sequence to a set.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 2, 2, 3, 3])\n\u003e\u003e\u003e seq.to_set()\n{1, 2, 3}\n\u003e\u003e\u003e\n```\n\n### all\n\nChecks if all elements satisfy a condition.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([2, 4, 6])\n\u003e\u003e\u003e seq.all(lambda x: x % 2 == 0)\nTrue\n\u003e\u003e\u003e seq.all(lambda x: x \u003e 5)\nFalse\n\u003e\u003e\u003e\n```\n\n### none\n\nChecks if no elements satisfy a condition.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 3, 5])\n\u003e\u003e\u003e seq.none(lambda x: x % 2 == 0)\nTrue\n\u003e\u003e\u003e seq.none(lambda x: x \u003c 5)\nFalse\n\u003e\u003e\u003e\n```\n\n### any\n\nChecks if any elements satisfy a condition.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 2, 3])\n\u003e\u003e\u003e seq.any(lambda x: x % 2 == 0)\nTrue\n\u003e\u003e\u003e seq.any(lambda x: x \u003e 5)\nFalse\n\u003e\u003e\u003e\n```\n\n### max\n\nFinds the maximum element.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 3, 2])\n\u003e\u003e\u003e seq.max()\n3\n\u003e\u003e\u003e\n```\n\n### max_or_none\n\nFinds the maximum element, or returns `None` for an empty sequence.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 3, 2])\n\u003e\u003e\u003e seq.max_or_none()\n3\n\u003e\u003e\u003e seq = Seq([])\n\u003e\u003e\u003e seq.max_or_none()\n\u003e\u003e\u003e\n```\n\n### max_by\n\nFinds the element which maximizes a specified function.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq(['a', 'abc', 'ab'])\n\u003e\u003e\u003e seq.max_by(len)\n'abc'\n\u003e\u003e\u003e\n```\n\n### max_by_or_none\n\nLike `max_by`, but returns `None` for an empty sequence.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq(['a', 'abc', 'ab'])\n\u003e\u003e\u003e seq.max_by_or_none(len)\n'abc'\n\u003e\u003e\u003e seq = Seq([])\n\u003e\u003e\u003e seq.max_by_or_none(len)\n\u003e\u003e\u003e\n```\n\n### min\n\nFinds the minimum element.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([3, 1, 2])\n\u003e\u003e\u003e seq.min()\n1\n\u003e\u003e\u003e\n```\n\n### min_or_none\n\nFinds the minimum element, or returns `None` for an empty sequence.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 3, 2])\n\u003e\u003e\u003e seq.min_or_none()\n1\n\u003e\u003e\u003e seq = Seq([])\n\u003e\u003e\u003e seq.min_or_none()\n\u003e\u003e\u003e\n```\n\n### min_by\n\nFinds the element which minimizes a specified function.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq(['abc', 'a', 'ab'])\n\u003e\u003e\u003e seq.min_by(len)\n'a'\n\u003e\u003e\u003e\n```\n\n### min_by_or_none\n\nLike `min_by`, but returns `None` for an empty sequence.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq(['abc', 'a', 'ab'])\n\u003e\u003e\u003e seq.min_by_or_none(len)\n'a'\n\u003e\u003e\u003e seq = Seq([])\n\u003e\u003e\u003e seq.min_by_or_none(len)\n\u003e\u003e\u003e\n```\n\n### single\n\nReturns the single element of the sequence, and throws an error if the sequence does not contain exactly one element.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([9]).single()\n9\n\u003e\u003e\u003e # Seq([]).single()  # ERROR\n\u003e\u003e\u003e # Seq([1, 2]).single()  # ERROR\n\u003e\u003e\u003e\n```\n\n### single_or_none\n\nReturns the single element of the sequence, or `None` if the sequence is empty. Throws an error if the sequence contains more than one element.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([9]).single_or_none()\n9\n\u003e\u003e\u003e Seq([]).single_or_none()\n\u003e\u003e\u003e Seq([1, 2]).single_or_none()\n\u003e\u003e\u003e\n```\n\n### first\n\nReturns the first element of the sequence. Throws an error if the sequence is empty.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([7, 8, 9]).first()\n7\n\u003e\u003e\u003e # Seq([]).first()  # ERROR\n\u003e\u003e\u003e\n```\n\n### first_or_none\n\nReturns the first element of the sequence, or `None` if the sequence is empty.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([7, 8, 9]).first_or_none()\n7\n\u003e\u003e\u003e Seq([]).first_or_none()\n\u003e\u003e\u003e\n```\n\n### last\n\nReturns the last element of the sequence. Throws an error if the sequence is empty.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([7, 8, 9]).last()\n9\n\u003e\u003e\u003e # Seq([]).last()  # ERROR\n\u003e\u003e\u003e\n```\n\n### last_or_none\n\nReturns the last element of the sequence, or `None` if the sequence is empty.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([7, 8, 9]).last_or_none()\n9\n\u003e\u003e\u003e Seq([]).last_or_none()\n\u003e\u003e\u003e\n```\n\n### drop\n\nReturns a new sequence with the first `n` elements removed.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([1, 2, 3, 4]).drop(2).to_list()\n[3, 4]\n\u003e\u003e\u003e\n```\n\n### drop_while\n\nReturns a new sequence by dropping elements as long as the predicate is true.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 2, 3, 4, 1])\n\u003e\u003e\u003e seq.drop_while(lambda x: x \u003c 3).to_list()\n[3, 4, 1]\n\u003e\u003e\u003e\n```\n\n### take\n\nReturns a new sequence containing the first `n` elements.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([1, 2, 3, 4]).take(2).to_list()\n[1, 2]\n\u003e\u003e\u003e\n```\n\n### take_while\n\nReturns a new sequence by taking elements as long as the predicate is true.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 2, 3, 4, 1])\n\u003e\u003e\u003e seq.take_while(lambda x: x \u003c 3).to_list()\n[1, 2]\n\u003e\u003e\u003e\n```\n\n### sorted\n\nReturns a new sequence with elements sorted in ascending order.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([3, 1, 4]).sorted().to_list()\n[1, 3, 4]\n\u003e\u003e\u003e\n```\n\n### sorted_by\n\nSorts elements by a specified key function.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq(['apple', 'banana', 'cherry'])\n\u003e\u003e\u003e seq.sorted_by(lambda x: x[0]).to_list()\n['apple', 'banana', 'cherry']\n\u003e\u003e\u003e\n```\n\n### sorted_desc\n\nReturns a new sequence with elements sorted in descending order.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([3, 1, 4]).sorted_desc().to_list()\n[4, 3, 1]\n\u003e\u003e\u003e\n```\n\n### sorted_by_desc\n\nSorts elements by a specified key function in descending order.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq(['apple', 'banana', 'cherry'])\n\u003e\u003e\u003e seq.sorted_by_desc(lambda x: x[0]).to_list()\n['cherry', 'banana', 'apple']\n\u003e\u003e\u003e\n```\n\n### chunked\n\nSplits the sequence into chunks of the specified size.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([1, 2, 3, 4, 5]).chunked(2).to_list()\n[[1, 2], [3, 4], [5]]\n\u003e\u003e\u003e\n```\n\n### enumerate\n\nAdds an index to each element of the sequence.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq(['a', 'b', 'c']).enumerate().to_list()\n[(0, 'a'), (1, 'b'), (2, 'c')]\n\u003e\u003e\u003e\n```\n\n### shuffled\n\nReturns a new sequence with elements shuffled in random order.\n\n```python\n\u003e\u003e\u003e import random\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 2, 3, 4, 5])\n\u003e\u003e\u003e rng = random.Random(42)  # custom pseudo-random number generator, Optional\n\u003e\u003e\u003e seq.shuffled(rng).to_list()\n[4, 2, 3, 5, 1]\n\u003e\u003e\u003e\n```\n\n### reduce\n\nReduces the sequence to a single value by applying a binary operation. Throws an error if the sequence is empty.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([1, 2, 3, 4]).reduce(lambda x, y: x + y)\n10\n\u003e\u003e\u003e\n```\n\n### reduce_or_none\n\nLike `reduce`, but returns `None` for an empty sequence.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([1, 2, 3, 4]).reduce_or_none(lambda x, y: x + y)\n10\n\u003e\u003e\u003e Seq([]).reduce_or_none(lambda x, y: x + y)\n\u003e\u003e\u003e\n```\n\n### sum\n\nSums the elements in the sequence. Throws an error if the sequence is empty.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([1, 2, 3, 4]).sum()\n10\n\u003e\u003e\u003e\n```\n\n\n### sum_or_none\n\nCalculates the sum of all elements in the sequence, or returns `None` if the sequence is empty.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([1, 2, 3, 4]).sum_or_none()\n10\n\u003e\u003e\u003e Seq([]).sum_or_none()\n\u003e\u003e\u003e\n```\n\n### distinct\n\nReturns a new sequence with distinct elements.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e Seq([1, 2, 2, 3, 3]).distinct().to_list()\n[1, 2, 3]\n\u003e\u003e\u003e\n```\n\n### distinct_by\n\nReturns a new sequence with elements that are distinct based on the specified key function.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq(['apple', 'banana', 'apricot'])\n\u003e\u003e\u003e seq.distinct_by(lambda x: x[0]).to_list()\n['apple', 'banana']\n\u003e\u003e\u003e\n```\n\n### for_each\n\nApplies an action to each element of the sequence.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e result = []\n\u003e\u003e\u003e Seq([1, 2, 3]).for_each(lambda x: print(x))\n1\n2\n3\n\u003e\u003e\u003e\n```\n\n### join_to_string\n\nConcatenates elements of the sequence into a single string with specified separators and optional prefix/suffix.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq(['apple', 'banana', 'cherry'])\n\u003e\u003e\u003e seq.join_to_string(separator=\", \", prefix=\"[\", suffix=\"]\")\n'[apple, banana, cherry]'\n\u003e\u003e\u003e\n```\n\n### partition\n\nSplits the sequence into two sequences based on a predicate. The first sequence contains elements for which the predicate is true, and the second contains elements for which it is false.\n\n```python\n\u003e\u003e\u003e from kothon import Seq\n\u003e\u003e\u003e\n\u003e\u003e\u003e seq = Seq([1, 2, 3, 4, 5])\n\u003e\u003e\u003e true_part, false_part = seq.partition(lambda x: x % 2 == 0)\n\u003e\u003e\u003e true_part\n[2, 4]\n\u003e\u003e\u003e false_part\n[1, 3, 5]\n\u003e\u003e\u003e\n```\n\n## Contributing\n\nWe welcome contributions! If you have improvements or bug fixes, please feel free to create a pull request.\n\n## Acknowledgments\n\nKothon is inspired by the Kotlin Sequence class and the broader functional programming paradigm. We are grateful to the\nKotlin community for their innovative work, which has inspired the creation of this library.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fklahap%2Fkothon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fklahap%2Fkothon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fklahap%2Fkothon/lists"}