# Generate successive k-length permutations. (2.00) # @see 3UOMj3 def permutations(iterable, k=None): def detail(a, i, k): if i == k: yield tuple(a[:k]) else: n = len(a) j = i while True: yield from detail(a, i+1, k) j += 1 if j == n: break a[i], a[j] = a[j], a[i] a.append(a.pop(i)) a = list(iterable) n = len(a) k = n if k is None else k return detail(a, 0, k) if k <= n else [] # Test. import itertools import time n = 3 a = list(range(n)) for k in range(2+len(a)): print(list(permutations(a, k))) print(list(itertools.permutations(a, k))) def test(f, a): t = time.process_time() for _ in f(a): pass t = time.process_time() - t print('Elapsed: {:.6f}s'.format(t)) m = sum(1 for _ in f(a)) n = sum(1 for _ in itertools.permutations(a)) assert m == n for x, y in zip(f(a), itertools.permutations(a)): assert x == y n = 8 a = list(range(n)) test(permutations, a) test(itertools.permutations, a)
Standard input is empty
[()] [()] [(0,), (1,), (2,)] [(0,), (1,), (2,)] [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)] [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)] [(0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 0, 1), (2, 1, 0)] [(0, 1, 2), (0, 2, 1), (1, 0, 2), (1, 2, 0), (2, 0, 1), (2, 1, 0)] [] [] Elapsed: 0.061983s Elapsed: 0.004203s