Skip to content

bclmary/cyclic_sequences

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

Indexing

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'

Slicing

  • 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]
    []

Methods

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'])

Notable edge effects

All following properties are valid for CyclicTuple, CyclicList and CyclicStr, named below cyclic classes.

  • Indexing an empty cyclic class returns an IndexError.
  • Indexing on a unique element returns always this element.
  • Slicing a cyclic class returns the base class (ie slicing a CyclicStr returns a string).

About

A collection of cyclic sequence type objects.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages