Is there an alternative to python permutations for input generator?

I am trying to use an unlimited generator in itertools.permutations, but it does not seem to work. A return generator is never created because the function only works forever. To understand what I mean, think:

from itertools import count, permutations
all_permutations = permutations(count(1), 4)

As I imagine, this work consists in the fact that it generates all possible 4-dimensional permutations from the first 4 natural numbers. Then it should generate all possible 4-dimensional permutations of the first 5 natural numbers, without repetitions, so 5 should be included in all of these. What happens is that python hangs upon creation all_permutations.

Before I leave and create my own function from scratch, I wonder if there is another library that could do what I'm looking for? Also, shouldn't this built-in function handle this? Perhaps this is a bug that needs to be developed?

EDIT: for some iterations ...

1 2 3 4
1 2 4 3
...
4 3 2 1
1 2 3 5
1 2 5 3
...
5 3 2 1
1 2 4 5
1 2 5 4
...
+4
source share
2 answers

Good question! Here's an efficient method that generates them systematically, without repetition (and without the need to check):

  • First, rearrange the first elements n;
  • then permutations , including the n+1st-element and the n-1previous ones,
  • then those associated with the n+2nd element and n-1previous ones, etc.

, . (, ).

, : 1 base n-1 .

from itertools import islice, permutations, combinations

def step_permutations(source, n):
    """Return a potentially infinite number of permutations, in forward order"""

    isource = iter(source)
    # Advance to where we have enough to get started
    base = tuple(islice(isource, n-1))

    # permutations involving additional elements:
    # the last-selected one, plus <n-1> of the earlier ones
    for x in isource:
        # Choose n-1 elements plus x, form all permutations
        for subset in combinations(base, n-1):
            for perm in permutations(subset + (x,), n):
                yield perm

        # Now add it to the base of elements that can be omitted 
        base += (x,)

:

>>> for p in step_permutations(itertools.count(1), 3):
    print(p)

(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)
(1, 2, 4)
(1, 4, 2)
(2, 1, 4)
(2, 4, 1)
(4, 1, 2)
(4, 2, 1)
(1, 3, 4)
(1, 4, 3)
(3, 1, 4)
(3, 4, 1)
(4, 1, 3)
(4, 3, 1)
(2, 3, 4)
(2, 4, 3)
(3, 2, 4)
...
+2

- :

from itertools import count, permutations

def my_permutations(gen, n=4):
    i = iter(gen)
    population = []
    seen = set()
    while True:
        for p in permutations(population, n):
            if p not in seen:
                yield p
                seen.add(p)
        population.append(next(i))

, , , .

:

def my_permutations(gen, n=4):
    i = iter(gen)
    population = []
    while True:
        population.append(next(i))
        *first, last = population
        perms = permutations(first, n-1)
        yield from (p[:i] + (last,) + p[i:] for p in perms for i in range(n))
+4

Source: https://habr.com/ru/post/1686497/


All Articles