Skip to main content
Cyclic-Sequences
################

Sequence type objects with cyclic indexing::

Description
===========

The cyclic indexation works as for usual sequences, with the possible use
of negative indexes. But it makes a jump-back to the beginning (or the end for
negative indexes) if the index is higher than the length of the sequence::

┌───────────────────────────┐
│ ▼
┏━│━┳━━━┳━━━┳━╍┅ ┅╍━┳━━━━━┳━━━┳━━━┓
┃ ● ┃ 0 ┃ 1 ┃ ⋅⋅⋅ ┃ N-1 ┃ N ┃ ● ┃
┗━━━┻━━━┻━━━┻━╍┅ ┅╍━┻━━━━━┻━━━┻━│━┛
▲ │
└───────────────────────────┘

Iterating over a cyclic sequence is bounded (no infinite loop).


.. note:: This module is based on a Chris Lawlor forum publication.


Content
=======

:CyclicTuple:
Class object.
An immutable cyclic sequence based on built-in class *tuple*.

:CyclicList:
Class object.
A mutable cyclic sequence based on built-in class *list*.

:CyclicStr:
Class object.
An immutable cyclic sequence based on built-in class *str*.


Immutable class methods
-----------------------

:with_first:
foo.with_first(elt) -> new instance
New instance of 'foo' with first occurence of 'elt' at first position.
Raises ValueError if 'elt' is not present.

:turned:
foo.turned(step) -> new instance
New instance of 'foo' with all elements shifted of given step.
(default is 1 unit onward).


Mutable class methods
---------------------

:set_first:
foo.set_first(elt) -> None
Set first occurence of 'elt' at first position.
Raises ValueError if 'elt' is not present.

:turn:
foo.turn(step) -> None
Change all elements indexes of given step (default is 1 unit onward)
Equivalent to set at first position the element at index 'step'.


Examples
========

The following examples are using CyclicList class for demonstration. CyclicTuple and CyclicStr classes get similar behaviours.

- Construction from any iterable::

>>> foo = CyclicList(['a', 'b', 'c', 'd', 'e'])
>>> foo
CyclicList(['a', 'b', 'c', 'd', 'e'])

- Gets its specific string representation with chevrons figuring cycling::

>>> print(foo)
<['a', 'b', 'c', 'd', 'e']>

- Accessing works like a regular list::

>>> foo[1]
'b'
>>> foo[-4]
'b'

- Except indexes higher than length wraps around::

>>> foo[6]
'b'
>>> foo[11]
'b'
>>> foo[-9]
'b'

- Slices work and return list objects::

>>> foo[1:4]
['b', 'c', 'd']
>>> foo[3:0:-1]
['d', 'c', 'b']

- Slices work also out of range with cyclic output::

>>> foo[3:7]
['d', 'e', 'a', 'b']
>>> foo[8:12]
['d', 'e', 'a', 'b']
>>> foo[3:12]
['d', 'e', 'a', 'b', 'c', 'd', 'e', 'a', 'b']
>>> foo[-2:2]
['d', 'e', 'a', 'b']
>>> foo[-7:-3]
['d', 'e', 'a', 'b']
>>> foo[-7:2]
['d', 'e', 'a', 'b', 'c', 'd', 'e', 'a', 'b']

- Slices with non unitary steps work also::

>>> foo[:7:2]
['a', 'c', 'e', 'b']
>>> foo[:7:3]
['a', 'd', 'b']
>>> foo[:7:5]
['a', 'a']

- As well for reversed steps::

>>> foo[1:-3:-1]
['b', 'a', 'e', 'd']
>>> foo[-4:-8:-1]
['b', 'a', 'e', 'd']
>>> foo[-4:-9:-2]
['b', 'e', 'c']
>>> foo[-4:-9:-3]
['b', 'd']
>>> foo[-5:-11:-5]
['a', 'a']

- Incoherent slices return empty list::

>>> foo[11:5]
[]

Edge effects:

- Indexing an empty CyclicList returns an IndexError.

- Indexing on a unique element returns always this element.


First element can be played with using specific methods:

- **with_first**: return a new CyclicList with given element at first
position::

>>> foo.with_first('c')
CyclicList(['c', 'd', 'e', 'a', 'b'])

- **turned**: return a new CyclicList with all elements indexes changed
of given step (default is 1 unit onward)::

>>> foo.turned()
CyclicList(['b', 'c', 'd', 'e', 'a'])
>>> foo.turned(-3)
CyclicList(['c', 'd', 'e', 'a', 'b'])
>>> foo.turned(10)
CyclicList(['a', 'b', 'c', 'd', 'e'])

- **set_first**: put given element at first position::

>>> foo.set_first('c')
>>> foo
CyclicList(['c', 'd', 'e', 'a', 'b'])

- **turn**: change all elements index of given step
(default is 1 unit onward)::

>>> foo.turn()
>>> foo
CyclicList(['d', 'e', 'a', 'b', 'c'])
>>> foo.turn(-3)
>>> foo
CyclicList(['a', 'b', 'c', 'd', 'e'])
>>> foo.turn(11)
>>> foo
CyclicList(['b', 'c', 'd', 'e', 'a'])


Metadata

Release files for cyclic-sequences 1.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distribution (wheel)

Table of built distributions (wheels) for cyclic-sequences 1.1.2
File Interpreter ABI Platform
cyclic_sequences-1.1.2-py3-none-any.whl Python 3 none any Details

Release files / cyclic_sequences-1.1.2-py3-none-any.whl

Download URL cyclic_sequences-1.1.2-py3-none-any.whl
Size 8.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1e0aa2103d49c27c8e9f98b76bfee84de9a340e45af2643e07ca7552e8052ecd
BLAKE2b-256 checksum
How to use checksums
bfd5a8384de1ee2b69dc2270ec0a4509213fd4384e14eaf6b53ed6f3478422a4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.10.0 pkginfo/1.2.1 requests/2.18.4 setuptools/39.0.1 requests-toolbelt/0.8.0 tqdm/4.19.5 CPython/3.6.5

Release history Release notifications | RSS feed

This release

1.1.2 This release

1 release file

1.1.1

1 release file

1.1.0

1 release file

1.0.0

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page