lazystuff


Namelazystuff JSON
Version 1.2.0 PyPI version JSON
download
home_pageNone
SummaryLazy-ish list-like objects for streaming APIs.
upload_time2024-11-07 14:24:36
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseAGPL-3.0-or-later
keywords lazy sequence
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # lazystuff documentation

The [`lazystuff`](#module-lazystuff) package provides lazy-ish list-like objects.

This package implements a single data type, `lazylist`, that
behaves almost like a regular list. It has all the normal list methods
and operators and they work as expected with a single exception.

When a `lazylist` is extended with an iterable other than a
regular list, evaluation of the iterable is deferred until it is
needed, and is limited to the number of elements required. The
elements that are fetched from the iterator(s) are stored as a regular
list inside the `lazylist`.

Iteration only takes place when an element is requested. For example:

* When checking if the list is empty (or non-empty), a single element
  is fetched.
* When indexing the list using a positive number, elements are fetched
  until the requested index is reached.
* When the `index()` method is called, elements are fetched
  until the requested value is found.

There are situations when all iterators are exhausted, including:

* When the length of the list is requested.
* When using the in operator and the value is not in the list.
* When calling `index()` with a value that is not in the list.
* When the list is printed (all elements are printed).
* When the list is indexed with a negative number.
* When the `remove()`, `count()`, or `sort()` methods are called.
* When equal lists are compared.
* When the list is pickled.

For example, a `lazylist()` can represent an infinite sequence:

```default
all_squares = lazylist(x * x for x in itertools.count())
print(squares[99])  # Only iterates 100 times
```

Multiple sequences can be added to a lazylist and regular lists and
iterators can be mixed:

```default
>>> example = lazylist(['a', 'b', 'c'])
>>> example.extend(range(1, 4))
>>> example.extend(string.ascii_lowercase[3:6])
>>> print(example[3])
1
>>> del example[6]
>>> print(example)
['a', 'b', 'c', 1, 2, 3, 'e', 'f']
```

When the list is indexed with 3, a single element is fetched from the
range iterator. When element 6 is deleted, the range iterator is
exhausted and a single element is fetched from the string iterator in
order to reach the element at index 6. Finally, the string iterator is
also exhausted when the list is printed. The `repr()` function
to see the current status of the list:

```default
 >>> example = lazylist(['a', 'b', 'c'])
 >>> example.extend(range(1, 4))
 >>> example.extend(string.ascii_lowercase[3:6])
 >>> repr(example)
 "<lazylist ['a', 'b', 'c'] [<range_iterator ...> <str_ascii_iterator ...>]>"
 >>> print(example[3])
 1
 >>> repr(example)
 "<lazylist ['a', 'b', 'c', 1] [<range_iterator ...> <str_ascii_iterator ...>]>"
 >>> del example[6]
 >>> repr(example)
"<lazylist ['a', 'b', 'c', 1, 2, 3] [<str_ascii_iterator object at ...>]>"
 >>> print(example)
 ['a', 'b', 'c', 1, 2, 3, 'e', 'f']
 >>> repr(example)
 "<lazylist ['a', 'b', 'c', 1, 2, 3, 'e', 'f'] []>"
```

The representation contains two elements: first the list of list
elements that have been fetched from the iterators and second the list
of iterators and regular lists that have been added to the
`lazylist`.

`lazylist` was originally developed to simplify streaming
results from an API to a receiver with the goal that results should be
sent to the receiver as they became available and that if the process
were aborted, no unnecessary calls to the API should have been made.

The resulting code with `lazylist` was similar to this:

```default
results = lazylist(api.search(query))
if not results:
    print('Nothing found')
else:
    for result in results:
        print_result(result)
```

The api.search method returns a generator that yields one item at a
time from the API. By representing the results as a
`lazylist` the code for checking if there are any results
and then iterating over them is very simple. The corresponding code
without `lazylist` would be something like this:

```default
results = api.search(query)
results_iter_1, results_iter_2 = itertools.tee(results)
if not results_iter_1:
    print('Nothing found')
else:
    for result in results_iter_2:
        print_result(result)
```

Additional tee iterators would be needed if the results were to be
processed multiple times, and it would be impossible to perform
indexed access on the results, which is sometimes a requirement.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "lazystuff",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "lazy, sequence",
    "author": null,
    "author_email": "David Byers <david.byers@liu.se>",
    "download_url": "https://files.pythonhosted.org/packages/ea/f7/944432df5d446f5db3b6971839021a15600b131e0e70beb86072e2ba1e1c/lazystuff-1.2.0.tar.gz",
    "platform": null,
    "description": "# lazystuff documentation\n\nThe [`lazystuff`](#module-lazystuff) package provides lazy-ish list-like objects.\n\nThis package implements a single data type, `lazylist`, that\nbehaves almost like a regular list. It has all the normal list methods\nand operators and they work as expected with a single exception.\n\nWhen a `lazylist` is extended with an iterable other than a\nregular list, evaluation of the iterable is deferred until it is\nneeded, and is limited to the number of elements required. The\nelements that are fetched from the iterator(s) are stored as a regular\nlist inside the `lazylist`.\n\nIteration only takes place when an element is requested. For example:\n\n* When checking if the list is empty (or non-empty), a single element\n  is fetched.\n* When indexing the list using a positive number, elements are fetched\n  until the requested index is reached.\n* When the `index()` method is called, elements are fetched\n  until the requested value is found.\n\nThere are situations when all iterators are exhausted, including:\n\n* When the length of the list is requested.\n* When using the in operator and the value is not in the list.\n* When calling `index()` with a value that is not in the list.\n* When the list is printed (all elements are printed).\n* When the list is indexed with a negative number.\n* When the `remove()`, `count()`, or `sort()` methods are called.\n* When equal lists are compared.\n* When the list is pickled.\n\nFor example, a `lazylist()` can represent an infinite sequence:\n\n```default\nall_squares = lazylist(x * x for x in itertools.count())\nprint(squares[99])  # Only iterates 100 times\n```\n\nMultiple sequences can be added to a lazylist and regular lists and\niterators can be mixed:\n\n```default\n>>> example = lazylist(['a', 'b', 'c'])\n>>> example.extend(range(1, 4))\n>>> example.extend(string.ascii_lowercase[3:6])\n>>> print(example[3])\n1\n>>> del example[6]\n>>> print(example)\n['a', 'b', 'c', 1, 2, 3, 'e', 'f']\n```\n\nWhen the list is indexed with 3, a single element is fetched from the\nrange iterator. When element 6 is deleted, the range iterator is\nexhausted and a single element is fetched from the string iterator in\norder to reach the element at index 6. Finally, the string iterator is\nalso exhausted when the list is printed. The `repr()` function\nto see the current status of the list:\n\n```default\n >>> example = lazylist(['a', 'b', 'c'])\n >>> example.extend(range(1, 4))\n >>> example.extend(string.ascii_lowercase[3:6])\n >>> repr(example)\n \"<lazylist ['a', 'b', 'c'] [<range_iterator ...> <str_ascii_iterator ...>]>\"\n >>> print(example[3])\n 1\n >>> repr(example)\n \"<lazylist ['a', 'b', 'c', 1] [<range_iterator ...> <str_ascii_iterator ...>]>\"\n >>> del example[6]\n >>> repr(example)\n\"<lazylist ['a', 'b', 'c', 1, 2, 3] [<str_ascii_iterator object at ...>]>\"\n >>> print(example)\n ['a', 'b', 'c', 1, 2, 3, 'e', 'f']\n >>> repr(example)\n \"<lazylist ['a', 'b', 'c', 1, 2, 3, 'e', 'f'] []>\"\n```\n\nThe representation contains two elements: first the list of list\nelements that have been fetched from the iterators and second the list\nof iterators and regular lists that have been added to the\n`lazylist`.\n\n`lazylist` was originally developed to simplify streaming\nresults from an API to a receiver with the goal that results should be\nsent to the receiver as they became available and that if the process\nwere aborted, no unnecessary calls to the API should have been made.\n\nThe resulting code with `lazylist` was similar to this:\n\n```default\nresults = lazylist(api.search(query))\nif not results:\n    print('Nothing found')\nelse:\n    for result in results:\n        print_result(result)\n```\n\nThe api.search method returns a generator that yields one item at a\ntime from the API. By representing the results as a\n`lazylist` the code for checking if there are any results\nand then iterating over them is very simple. The corresponding code\nwithout `lazylist` would be something like this:\n\n```default\nresults = api.search(query)\nresults_iter_1, results_iter_2 = itertools.tee(results)\nif not results_iter_1:\n    print('Nothing found')\nelse:\n    for result in results_iter_2:\n        print_result(result)\n```\n\nAdditional tee iterators would be needed if the results were to be\nprocessed multiple times, and it would be impossible to perform\nindexed access on the results, which is sometimes a requirement.\n",
    "bugtrack_url": null,
    "license": "AGPL-3.0-or-later",
    "summary": "Lazy-ish list-like objects for streaming APIs.",
    "version": "1.2.0",
    "project_urls": {
        "Homepage": "https://github.com/ookisan/lazystuff",
        "Issues": "https://github.com/ookisan/lazystuff/issues"
    },
    "split_keywords": [
        "lazy",
        " sequence"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "02d55d905125370016e8620e6d684ed90f941204acff9015384f34aab4af4bb6",
                "md5": "7c76d93a87e0d30ecd24fdb6b6e6363c",
                "sha256": "c3ca77ae7442775adead0a216427f851290d749ad214386d46e3d9c745bad2af"
            },
            "downloads": -1,
            "filename": "lazystuff-1.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "7c76d93a87e0d30ecd24fdb6b6e6363c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 24039,
            "upload_time": "2024-11-07T14:24:35",
            "upload_time_iso_8601": "2024-11-07T14:24:35.522649Z",
            "url": "https://files.pythonhosted.org/packages/02/d5/5d905125370016e8620e6d684ed90f941204acff9015384f34aab4af4bb6/lazystuff-1.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "eaf7944432df5d446f5db3b6971839021a15600b131e0e70beb86072e2ba1e1c",
                "md5": "c5400b0cb117b5b95449b977c06d9dff",
                "sha256": "9f38e15a2eaaf04ae673d439e1afaf0d150b6608f239637837e1b6057889cb0c"
            },
            "downloads": -1,
            "filename": "lazystuff-1.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "c5400b0cb117b5b95449b977c06d9dff",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 22541,
            "upload_time": "2024-11-07T14:24:36",
            "upload_time_iso_8601": "2024-11-07T14:24:36.637804Z",
            "url": "https://files.pythonhosted.org/packages/ea/f7/944432df5d446f5db3b6971839021a15600b131e0e70beb86072e2ba1e1c/lazystuff-1.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-11-07 14:24:36",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ookisan",
    "github_project": "lazystuff",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "lazystuff"
}
        
Elapsed time: 9.73190s