File: permutations.py

package info (click to toggle)
python-picklable-itertools 0.1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 172 kB
  • sloc: python: 1,222; makefile: 3
file content (67 lines) | stat: -rw-r--r-- 2,033 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
from abc import ABCMeta, abstractmethod
import six
from .product import product
from .base import BaseItertool


@six.add_metaclass(ABCMeta)
class IndexBased(BaseItertool):
    def __init__(self, iterable, r=None):
        self._pool = tuple(iterable)
        self._r = r if r is not None else len(self._pool)
        self._iter = self._construct_iter()

    def _construct_iter(self):
        return product(range(len(self._pool)), repeat=self._r)

    @abstractmethod
    def _valid_indices(self, indices):
        pass

    def __next__(self):
        indices = next(self._iter)
        while not self._valid_indices(indices):
            indices = next(self._iter)
        return tuple(self._pool[i] for i in indices)


class permutations(IndexBased):
    """permutations(iterable[, r]) --> permutations object

    Return successive r-length permutations of elements in the iterable.

    permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)
    """
    def _valid_indices(self, indices):
        return len(set(indices)) == self._r


@six.add_metaclass(ABCMeta)
class AbstractCombinations(IndexBased):
    def __init__(self, iterable, r):
        super(AbstractCombinations, self).__init__(iterable, r)

    def _valid_indices(self, indices):
        return sorted(indices) == list(indices)


class combinations_with_replacement(AbstractCombinations):
    """combinations_with_replacement(iterable, r) -->
    combinations_with_replacement object

    Return successive r-length combinations of elements in the iterable
    allowing individual elements to have successive repeats.
    combinations_with_replacement('ABC', 2) --> AA AB AC BB BC CC
    """
    pass


class combinations(AbstractCombinations):
    """combinations(iterable, r) --> combinations object

    Return successive r-length combinations of elements in the iterable.

    combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)
    """
    def _construct_iter(self):
        return permutations(range(len(self._pool)), self._r)