{"id":48833809,"url":"https://github.com/ankitml/underscore","last_synced_at":"2026-04-14T22:04:10.019Z","repository":{"id":57458161,"uuid":"78935773","full_name":"ankitml/underscore","owner":"ankitml","description":null,"archived":false,"fork":false,"pushed_at":"2020-03-04T19:27:51.000Z","size":22447,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-10-28T17:10:23.294Z","etag":null,"topics":["collections","data-analysis","json","python3","underscore"],"latest_commit_sha":null,"homepage":null,"language":"Roff","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/ankitml.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}},"created_at":"2017-01-14T11:16:48.000Z","updated_at":"2020-03-04T19:27:56.000Z","dependencies_parsed_at":"2022-09-07T04:10:18.063Z","dependency_job_id":null,"html_url":"https://github.com/ankitml/underscore","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ankitml/underscore","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankitml%2Funderscore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankitml%2Funderscore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankitml%2Funderscore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankitml%2Funderscore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ankitml","download_url":"https://codeload.github.com/ankitml/underscore/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ankitml%2Funderscore/sbom","scorecard":{"id":197272,"data":{"date":"2025-08-11","repo":{"name":"github.com/ankitml/underscore","commit":"7e53982bda253fbd082af1d325c437f57c0014e1"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.9,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/19 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":9,"reason":"binaries present in source code","details":["Warn: binary detected: tutorial/ex1/underscore.pyc:1"],"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 12 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}}]},"last_synced_at":"2025-08-16T22:03:32.595Z","repository_id":57458161,"created_at":"2025-08-16T22:03:32.596Z","updated_at":"2025-08-16T22:03:32.596Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31817130,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T18:05:02.291Z","status":"ssl_error","status_checked_at":"2026-04-14T18:05:01.765Z","response_time":153,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["collections","data-analysis","json","python3","underscore"],"created_at":"2026-04-14T22:03:49.890Z","updated_at":"2026-04-14T22:04:10.004Z","avatar_url":"https://github.com/ankitml.png","language":"Roff","funding_links":[],"categories":[],"sub_categories":[],"readme":"\nBuild [![CircleCI](https://circleci.com/gh/ankitml/underscore/tree/master.svg?style=svg)](https://circleci.com/gh/ankitml/underscore/tree/master)\n\n## underscore\n\nUnderscorejs port for python\n\n## Highlights\n* Supports python 3. \n* All methods are lazy and return generators (well almost all)\n\n## Why\nUnderscore library has been very beneficial for working with collections in javascript. It has more than 60 functions, for manipulating, filtering, sorting, merging, grouping etc arrays in js. There is already a python port available in github called underscore.py, however it does not use generators and hence much more resource hogging. The goal of this repository is to provide very lightweight implementation in python and focus on performance along with ease of use. \n\n\"Underscore.js is the single most depended on module on npm.\" Python needs its own version of expressive list manipulation library.\n\n## Installation\n\nThis package is not yet available on pypy but you can install bleeding edge version by doing\n\n```\npip install pyunderscore\n```\nhttps://pypi.org/project/pyunderscore/\n\n## API\n\n\n#### each\n\nIterates over an iterable, yielding each element in turn to an iteratee function. \n\n\nparams: array, function/lambda\narray: the list whose elements will will be passed on the function one by one. This can be a generator as well yielding elements one by one. \nfunction -\u003e a function or lambda that takes either one or two inputs, element of the list, index of element. If it takes only one input then index will not be sent. \n\nReturns a generator of the input iterable, can be used for chaining purposes.\n\nExample: \n```python\n\u003e\u003e\u003e array = [1,10,100]\n\u003e\u003e\u003e iteratee1 = lambda val : print(val)\n\u003e\u003e\u003e iteratee2 = lambda val, index: print(index)\n\u003e\u003e\u003e lazy_each_object = _.each(_.each(array, iteratee1), iteratee2)\nThis lazy object is a generator and is not executed yet. This can be done wither by casting generator into a list, which returns the original array or iterating over it.\n\u003e\u003e\u003e list(lazy_each_object)\n\u003e\u003e\u003e 1\n\u003e\u003e\u003e 0\n\u003e\u003e\u003e 10\n\u003e\u003e\u003e 1\n\u003e\u003e\u003e 100\n\u003e\u003e\u003e 2\nNote the order or execution. All the iteratees are finished first for an element before the next element takes over. This can be changed by casting into list before passing it to next _.each method.\n\u003e\u003e\u003e not_so_lazy_each_object = list(_.each(list(_.each(array, iteratee1)), iteratee2))\n\u003e\u003e\u003e 1\n\u003e\u003e\u003e 10\n\u003e\u003e\u003e 100\n\u003e\u003e\u003e 0\n\u003e\u003e\u003e 1\n\u003e\u003e\u003e 2\n```\n\n\n#### map\n\nProduces a new stream of values (generator) by mapping each value in array \n\n(list, set, tuple, generator) through a transformation function (iteratee). \nThe iteratee is passed two arguments: the value, then the index (or key) of the iteration. If the iteratee can accept only one argument then only one will be sent\n\nparams: array, iteratee\n    array -\u003e a list, tuple, iterator, generator, dictionary\n    iteratee -\u003e a function or a lambda\n\nExamples:\n```python\nlist(_.map([1,2,3], lambda x: x*3))\n[3,6,9]\nlist(_.map({one: 1, two: 2, three: 3}, lambda key, val: val*3))\n[3,6,9]\nlist(_.map([[1, 2], [3, 4]], _.first))\n[1,3]\n```\n\n\n#### reduce\n\nAlso known as inject, foldl or fold-left, reduce boils down a list of values \n\ninto a single value. init is the initial state of the reduction, and each \nsuccessive step of it should be returned by iteratee. The iteratee is passed \nthree arguments: the current_reduced_state, then the value and index (or key) of the iteration.\n\nIf no init is passed to the initial invocation of reduce, the iteratee is not invoked on the first element of the list. The first element is instead passed as the memo in the invocation of the iteratee on the next element in the list. \n\nparams: iterable, iteratee, init\n    iterable -\u003e a list, tuple, iterator, generator, dictionary\n    iteratee -\u003e a function or a lambda\n    init -\u003e Inital value of the reduced state\n\nExamples:\n```python\n\u003e\u003e\u003e total = _.reduce([1, 2, 3], lambda memo, val: memo + val, 0);\n# \u003e\u003e\u003e twisted_total = _.reduce([1, 2, 3], lambda memo, val, index: memo + num*index, 0);\n```\n\n\n#### reduce_right\n\nNot implemented. Reduce right is also known as fold right. THere is no way this can be implemented with generators and hence skipped.\n\n\n\n#### find\n\nLooks through each value in the list, returning the first one that passes a truth test \n\nThe function yields as soon as it finds an acceptable element, and doesn't traverse the entire iterable\n\nparams: iterable, conditional\n    iterable -\u003e list, sequenece, set, dictionary, generator etc\n    conditional -\u003e a lambda or function that takes one or two inputs, first is element from iterable, second is index (optional)\n\nExamples:\n\n```python\nlist(_.find([1, 2, 3, 4, 5, 6], lambda x: x % 2 == 0))\n[2]\n```\n\nSince this returns a generator with a single value \"next\" can also be used to extract that value\n```python\nnext(_.find([1, 2, 3, 4, 5, 6], lambda x: x % 2 == 0))\n2\n```\n\nTODO: What happens if nothing is matched, generator would raise an exception on next\n\n\n#### select\n\n Looks through each value in the list, returning an array of all the values that pass a truth test (conditional). \n\n\nparams: conditional, iterable\n    iterable -\u003e list, sequenece, set, dictionary, generator etc\n    conditional -\u003e a lambda or function that takes one or two inputs, first is element from iterable, second is index (optional)\n\nExamples:\n\n```python\nlist(_.find([1, 2, 3, 4, 5, 6], lambda x: x % 2 == 0))\n[2, 4, 6]\n```\n\n\n#### where\n\n Looks through each value in the list, returning an array of all the values that contain all of the key-value pairs listed in properties. \n\n\n params: iterable, properties\n     iterable-\u003e a list/generator of dictionaries\n     properties-\u003e key value pairs which need to be in a dictionary.\n\n Examples:\n```python\nlist(_.where(list_of_plays, {author: \"Shakespeare\", year: 1611}))\n[{title: \"Cymbeline\", author: \"Shakespeare\", year: 1611}, {title: \"The Tempest\", author: \"Shakespeare\", year: 1611}]\n```\n\n\n#### find_where\n\n Looks through the list and returns the first value that matches all of the key-value pairs listed in properties. \n\nTODO what happens in case of no match?\n\nparams: iterable, properties\n     iterable-\u003e a list/generator of dictionaries\n     properties-\u003e key value pairs which need to be in a dictionary.\n\nExamples:\n```python\n\u003e\u003e\u003e list(_.findWhere(public_service_pulitzers, {\"newsroom\": \"The New York Times\"}))\n\u003e\u003e\u003e [{\"year\": 1918, \"newsroom\": \"The New York Times\",\n      \"reason\": \"For its public service in publishing in full so many official reports, documents and speeches by European statesmen relating to the progress and conduct of the war.\"}]\n```\n\nAlternatively, next function can be used to get the only value in the generator returned\n```python\nnext(_.findWhere(public_service_pulitzers, {\"newsroom\": \"The New York Times\"}))\n{\"year\": 1918, \n \"newsroom\": \"The New York Times\",\n \"reason\": \"For its public service in publishing in full so many official reports, documents and speeches by European statesmen relating to the progress and conduct of the war.\"}\n```\n\n\n#### reject\n\n Returns the values in list without the elements that the truth test (predicate) passes. The opposite of filter. \n\n\n params: iterable, conditional\n    iterable -\u003e list, sequenece, set, dictionary, generator etc\n    conditional -\u003e a lambda or function that takes one or two inputs, first is element from iterable, second is index (optional)\n\nExamples:\n```python\nodds = _.reject([1, 2, 3, 4, 5, 6], lambda x: x % 2 == 0)\nlist(odds)\n[1,3,5]\n```\n\n\n#### every\n\n Returns true if all of the values in the list pass the predicate truth test. Short-circuits and stops traversing the list if a false element is found. \n\n\n params: iterable, conditional\n    iterable -\u003e list, sequenece, set, dictionary, generator etc\n    conditional -\u003e a lambda or function that takes one or two inputs, first is element from iterable, second is index (optional)\nExamples:\n```python\n_.every([2, 4, 5], lambda x: x % 2 == 0)\nFalse\n```\n\n\n#### some\n\n Returns true if any of the values in the list pass the predicate truth test. Short-circuits and stops traversing the list if a false element is found. \n\n\n params: iterable, conditional\n    iterable -\u003e list, sequenece, set, dictionary, generator etc\n    conditional -\u003e a lambda or function that takes one or two inputs, first is element from iterable, second is index (optional)\nExamples:\n```python\n_.some([2, 4, 5], lambda x: x % 2 == 0)\nTrue\n```\n\n\n#### contains\n\nReturns true if the value is present in the iterable. Use from_index to start your search at a given index.\n\n\nParams: iterable, value\n    iterable -\u003e list, sequenece, set, dictionary, generator etc\n    value -\u003e Any element that is to be searched in the iterable\n\nIMP: This method is not lazy\n\nExamples:\n```python\n_.contains([1, 2, 3], 3);\nTrue\n```\n\n\n#### invoke\n\n Calls the callable named by iteratee_name on each value in the iterable. Any extra arguments passed to invoke will be forwarded on to the method invocation. \n\n\n Difference with _.each, _.map: each takes in the callable object instead of callable objects' name as string. Also _.invoke returns the new iterable from values returned by the callable. In this sense this is much closer to _.map.\n\n params: iterable, iteratee_name, arguments [optional]\n    iterable -\u003e list, sequenece, set, dictionary, generator etc\n    iteratee_name -\u003e name of the function which is available in the score while executing the code\n    arguments -\u003e optional arguments that will be passed on to the iteratee function\n\nExamples\n```python\nlist(_.invoke([[5, 1, 7], [3, 2, 1]], 'sorted'))\n[[1, 5, 7], [1, 2, 3]]\nlist(_.invoke([[5, 1, 7], [3, 2, 1]], 'sorted', keyword_args={\"reverse\":False, \"key\": lambda x: x if x %2 == 0 else 0}))\n [[1, 5, 7] [3, 1, 2]]\n```\n\n\n#### pluck\n\n A convenient version of what is perhaps the most common use-case for map: extracting a list of property values from a dictionary like iterable. \n\n TODO: Identify non dictionary like iterables and raise Exception\n\n params: iterable, property_name\n    iterable-\u003e an iterable of dictionary like objects\n    property_name-\u003e name of property which you want to extract from the dictionaries\n\nExamples:\n```python\nstooges = [{\"name\": 'moe', \"age\": 40}, {\"name\": 'larry', \"age\": 50}, {\"name\": 'curly', \"age\": 60}];\nlist(_.pluck(stooges, 'name'))\n[\"moe\", \"larry\", \"curly\"]\n```\n\n\n#### max\n\n Returns the maximum value in list. If a key is provided, it will \n\n be used on each value to generate the criterion by which the value is ranked. If a key_func is provided it will be used as callable for every element to rank the items.\n Only one of the key options will be accepted, if both are given key_func will be ignored\n\n params: iterable, key [optional], key_func [optional]\n    iterable-\u003e an iterable of dictionary like objects\n    key-\u003e dictionary key for customizing comparisions in the elements of the iterable\n    key_func-\u003e a function or lambda, as custom key function that customizes comparison way\n\nExamples:\n```python\nstooges = [{\"name\": 'moe', \"age\": 40}, {\"name\": 'larry', \"age\": 50}, {\"name\": 'curly', \"age\": 60}];\nnext(_.max(stooges, key='age'))\n{\"name\":'curly', \"age\": 60}\nnext(_.max(stooges, key_func=lambda x: x.get('age')))\n{\"name\":'curly', \"age\": 60}\n```\n\n\n#### min\n\n Returns the minimum value in list. If a key is provided, it will \n\n be used on each value to generate the criterion by which the value is ranked. If a key_func is provided it will be used as callable for every element to rank the items.\n Only one of the key options will be accepted, if both are given key_func will be ignored\n\n params: iterable, key [optional], key_func [optional]\n    iterable-\u003e an iterable of dictionary like objects\n    key-\u003e dictionary key for customizing comparisions in the elements of the iterable\n    key_func-\u003e a function or lambda, as custom key function that customizes comparison way\n\nExamples:\n```python\nstooges = [{\"name\": 'moe', \"age\": 40}, {\"name\": 'larry', \"age\": 50}, {\"name\": 'curly', \"age\": 60}];\nnext(_.max(stooges, key='age'))\n{'moe': 40}\nnext(_.max(stooges, key_func=lambda x: x.get('age')))\n{'moe': 40}\n```\n\n\n#### sort_by\n\n Returns the sorted iterable in ascending order. If a key is provided, it will \n\n be used on each value to generate the criterion by which the value is ranked. If a key_func is provided it will be used as callable for every element to rank the items.\n Only one of the key options will be accepted, if both are given key_func will be ignored\n If reverse is provided, ranking is done in descending order\n\n params: iterable, key [optional], key_func [optional], reverse [optional]\n    iterable-\u003e an iterable of dictionary like objects\n    key-\u003e dictionary key for customizing comparisions in the elements of the iterable\n    key_func-\u003e a function or lambda, as custom key function that customizes comparison way\n    reverse -\u003e boolean, default is Ascending order, True makes is descending\n\nExamples:\n```python\nstooges = [{\"name\": 'moe', \"age\": 40}, {\"name\": 'larry', \"age\": 50}, {\"name\": 'curly', \"age\": 60}];\n_.sort_by(stooges, key='age')\n[{\"name\": 'moe', \"age\": 40}, {\"name\": 'larry', \"age\": 50}, {\"name\": 'curly', \"age\": 60}]\n_.sort_by(stooges, key='age', reverse=True)\n[{\"name\": 'curly', \"age\": 60}, {\"name\": 'larry', \"age\": 50}, {\"name\": 'moe', \"age\": 40}]\n```\n\n\n#### group_by\n\n Splits an iterable into sets, grouped by the result of running each value through iteratee. \n\n If iteratee is a string instead of a function, groups by the property named by iteratee on each of the values. \n\n params: iterable, iteratee\n    iterable -\u003e a list, tuple, iterator, generator\n    iteratee -\u003e a function or a lambda, taking single value as input and returning a transformed value on which iterable will be grouped\n\nReturns a dictionary\n\nExamples:\n```python\n_.group_by([1.3, 2.1, 2.4], lambda x:math.floor(x))\n{1: [1.3], 2: [2.1, 2.4]}\n```\n\n\n#### index_by\n\nConverts a list or iterable into a dictionary by using either key or key_func. \n\n\nparams: array, key [optional], key_func [optional]\n    array-\u003e list like iterable\n    key -\u003e assuming array as array of dictionaries, key is a dictionary_key which is present in all of the dictionaries.\n    key_func-\u003e  a function or lambda that takes an element of the iterable and returns the key or index for the dictionary output\n\nExamples:\n```python\nstooges = [{\"name\": 'moe', \"age\": 40}, {\"name\": 'larry', \"age\": 50}, {\"name\": 'curly', \"age\": 60}];\n_.index_by(stooges, key='age');\n{\n    \"40\": {\"name\": 'moe', \"age\": 40},\n    \"50\": {\"name\": 'larry', \"age\": 50},\n    \"60\": {\"name\": 'curly', \"age\": 60}\n}\n```\n\n\n#### count_by\n\nThink of it like a harry potter sorting hat, tells you final number of students in every group.\n\nSimilar to group_by, instead of returning a list with every grouped_key, returns count of grouped elements only.\n\nparams: array, iteratee\n    iterable-\u003e list, set, generator \n    iteratee-\u003e a function or a lambda for grouping the elements\n\nExamples\n```python\n_.count_by([1, 2, 3, 4, 5], lambda x: 'even' if x % 2 == 0 else 'odd')\n{\"odd\": 3, \"even\": 2}\n```\n\n\n#### shuffle\n\nReturns a shuffled copy of the list.\n\nCaution: DOes not work with unordered collections and generators\n\nparams: iterable\n    iterable -\u003e list, sequenece, \n\n\nExamples:\n```python\n_.shuffle([1, 2, 3, 4, 5, 6]);\n[4, 1, 6, 3, 5, 2]\n```\n\n\n#### sample\n\n Produce a random sample from the list. Pass a number to return n random elements from the list. Otherwise a single random item will be returned. \n\n\nCAUTION: Does not yet work with generators\nparams: iterable, n_sample\n    iterable -\u003e list, sequenece, set, dictionary\n    n_sample -\u003e number of random samples to be taken from iterable\n\nTODO: implement walker's method. current one is too inefficient\nhttp://code.activestate.com/recipes/576564-walkers-alias-method-for-random-objects-with-diffe/\nExamples:\n```python\n_.sample([1, 2, 3, 4, 5, 6])\n[4]\n_.sample([1, 2, 3, 4, 5, 6], 3)\n[1, 6, 2]\n```\n\n\n#### size\n\nReturns the length of an iterable. \n\nCaution: If this iterable is generator, this method would eat up the generator\n\nparams: iterable\n    iterable -\u003e list, sequenece, set, dictionary, generator etc\n\nExamples:\n```python\ngen = (i for i in range(0,10))\n_.size(gen)\n10\n```\n\n\n#### partition\n\n Splits the iterable into two iterators: one whose elements all satisfy conditional and one whose elements all do not satisfy conditional.\n\n\n params: iterators, conditional\n    iterable -\u003e list, sequenece, set, dictionary, generator etc\n    conditional -\u003e a lambda or function that takes one input and returns a boolean\n\nExamples:\n```python\neven, odd = _.partition([1,2,3,4,5,6,7,8,9], lambda x: x % 2 ==0)\nlist(even)\n[2,4,6,8]\nlist(odd)\n[1,3,5,7,9]\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fankitml%2Funderscore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fankitml%2Funderscore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fankitml%2Funderscore/lists"}