Rankers¶
- sage.combinat.ranker.from_list(l)[source]¶
Return a ranker from the list l.
INPUT:
l
– list
OUTPUT:
[rank, unrank]
– functionsEXAMPLES:
sage: import sage.combinat.ranker as ranker sage: l = [1,2,3] sage: r,u = ranker.from_list(l) sage: r(1) 0 sage: r(3) 2 sage: u(2) 3 sage: u(0) 1
>>> from sage.all import * >>> import sage.combinat.ranker as ranker >>> l = [Integer(1),Integer(2),Integer(3)] >>> r,u = ranker.from_list(l) >>> r(Integer(1)) 0 >>> r(Integer(3)) 2 >>> u(Integer(2)) 3 >>> u(Integer(0)) 1
- sage.combinat.ranker.on_fly()[source]¶
Return a pair of enumeration functions rank / unrank.
rank assigns on the fly an integer, starting from 0, to any object passed as argument. The object should be hashable. unrank is the inverse function; it returns None for indices that have not yet been assigned.
EXAMPLES:
sage: [rank, unrank] = sage.combinat.ranker.on_fly() sage: rank('a') 0 sage: rank('b') 1 sage: rank('c') 2 sage: rank('a') 0 sage: unrank(2) 'c' sage: unrank(3) sage: rank('d') 3 sage: unrank(3) 'd'
>>> from sage.all import * >>> [rank, unrank] = sage.combinat.ranker.on_fly() >>> rank('a') 0 >>> rank('b') 1 >>> rank('c') 2 >>> rank('a') 0 >>> unrank(Integer(2)) 'c' >>> unrank(Integer(3)) >>> rank('d') 3 >>> unrank(Integer(3)) 'd'
Todo
add tests as in combinat::rankers
- sage.combinat.ranker.rank_from_list(l)[source]¶
Return a rank function for the elements of
l
.INPUT:
l
– a duplicate free list (or iterable) of hashable objects
OUTPUT:
a function from the elements of
l
to0,...,len(l)
EXAMPLES:
sage: import sage.combinat.ranker as ranker sage: l = ['a', 'b', 'c'] sage: r = ranker.rank_from_list(l) sage: r('a') 0 sage: r('c') 2
>>> from sage.all import * >>> import sage.combinat.ranker as ranker >>> l = ['a', 'b', 'c'] >>> r = ranker.rank_from_list(l) >>> r('a') 0 >>> r('c') 2
For non elements a
ValueError
is raised, as with the usualindex
method of lists:sage: r('blah') Traceback (most recent call last): ... ValueError: 'blah' is not in dict
>>> from sage.all import * >>> r('blah') Traceback (most recent call last): ... ValueError: 'blah' is not in dict
Currently, the rank function is a
CallableDict
; but this is an implementation detail:sage: type(r) <class 'sage.misc.callable_dict.CallableDict'> sage: r {'a': 0, 'b': 1, 'c': 2}
>>> from sage.all import * >>> type(r) <class 'sage.misc.callable_dict.CallableDict'> >>> r {'a': 0, 'b': 1, 'c': 2}
With the current implementation, no error is issued in case of duplicate value in
l
. Instead, the rank function returns the position of some of the duplicates:sage: r = ranker.rank_from_list(['a', 'b', 'a', 'c']) sage: r('a') 2
>>> from sage.all import * >>> r = ranker.rank_from_list(['a', 'b', 'a', 'c']) >>> r('a') 2
Constructing the rank function itself is of complexity
O(len(l))
. Then, each call to the rank function consists of an essentially constant time dictionary lookup.
- sage.combinat.ranker.unrank(L, i)[source]¶
Return the \(i\)-th element of \(L\).
INPUT:
L
– list, tuple, finite enumerated set, etc.i
– integer
The purpose of this utility is to give a uniform idiom to recover the \(i\)-th element of an object
L
, whetherL
is a list, tuple (or more generally acollections.abc.Sequence
), an enumerated set, some old parent of Sage still implementing unranking in the method__getitem__
, or an iterable (seecollections.abc.Iterable
). See Issue #15919.EXAMPLES:
Lists, tuples, and other
sequences
:sage: from sage.combinat.ranker import unrank sage: unrank(['a','b','c'], 2) 'c' sage: unrank(('a','b','c'), 1) 'b' sage: unrank(range(3,13,2), 1) 5
>>> from sage.all import * >>> from sage.combinat.ranker import unrank >>> unrank(['a','b','c'], Integer(2)) 'c' >>> unrank(('a','b','c'), Integer(1)) 'b' >>> unrank(range(Integer(3),Integer(13),Integer(2)), Integer(1)) 5
Enumerated sets:
sage: unrank(GF(7), 2) 2 sage: unrank(IntegerModRing(29), 10) 10
>>> from sage.all import * >>> unrank(GF(Integer(7)), Integer(2)) 2 >>> unrank(IntegerModRing(Integer(29)), Integer(10)) 10
An iterable:
sage: unrank(NN,4) 4
>>> from sage.all import * >>> unrank(NN,Integer(4)) 4
An iterator:
sage: unrank(('a{}'.format(i) for i in range(20)), 0) 'a0' sage: unrank(('a{}'.format(i) for i in range(20)), 2) 'a2'
>>> from sage.all import * >>> unrank(('a{}'.format(i) for i in range(Integer(20))), Integer(0)) 'a0' >>> unrank(('a{}'.format(i) for i in range(Integer(20))), Integer(2)) 'a2'
Warning
When unranking an iterator, it returns the
i
-th element beyond where it is currently at:sage: from sage.combinat.ranker import unrank sage: it = iter(range(20)) sage: unrank(it, 2) 2 sage: unrank(it, 2) 5
>>> from sage.all import * >>> from sage.combinat.ranker import unrank >>> it = iter(range(Integer(20))) >>> unrank(it, Integer(2)) 2 >>> unrank(it, Integer(2)) 5
- sage.combinat.ranker.unrank_from_list(l)[source]¶
Return an unrank function from a list.
EXAMPLES:
sage: import sage.combinat.ranker as ranker sage: l = [1,2,3] sage: u = ranker.unrank_from_list(l) sage: u(2) 3 sage: u(0) 1
>>> from sage.all import * >>> import sage.combinat.ranker as ranker >>> l = [Integer(1),Integer(2),Integer(3)] >>> u = ranker.unrank_from_list(l) >>> u(Integer(2)) 3 >>> u(Integer(0)) 1