fork(1) download
  1. # Generate successive k-length permutations. (3.00)
  2. # @note This has come full circle to something very similar to the version that
  3. # appears at docs.python.org/3/library/itertools.html#itertools.permutations
  4. # @see 3UOMj3, vSELdo
  5.  
  6. def permutations(iterable, k=None):
  7. items = list(iterable)
  8. n = len(items)
  9. if k is None:
  10. k = n
  11. elif k > n:
  12. return
  13. cycle = list(range(k))
  14.  
  15. while True:
  16. yield tuple(items[:k])
  17. for i in reversed(range(k)):
  18. j = cycle[i] + 1
  19. if j < n:
  20. cycle[i] = j
  21. items[i], items[j] = items[j], items[i]
  22. break
  23. cycle[i] = i
  24. items.append(items.pop(i))
  25. else:
  26. return
  27.  
  28. # Test.
  29.  
  30. import itertools
  31. import time
  32.  
  33. n = 3
  34. a = list(range(n))
  35. for k in range(2+len(a)):
  36. print(list(permutations(a, k)))
  37. print(list(itertools.permutations(a, k)))
  38.  
  39. def test(f, a):
  40. t = time.process_time()
  41. for _ in f(a):
  42. pass
  43. t = time.process_time() - t
  44. print('Elapsed: {:.6f}s'.format(t))
  45. m = sum(1 for _ in f(a))
  46. n = sum(1 for _ in itertools.permutations(a))
  47. assert m == n
  48. for x, y in zip(f(a), itertools.permutations(a)):
  49. assert x == y
  50.  
  51. n = 8
  52. a = list(range(n))
  53. test(permutations, a)
  54. test(itertools.permutations, a)
Success #stdin #stdout 0.22s 14120KB
stdin
Standard input is empty
stdout
[()]
[()]
[(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.022065s
Elapsed: 0.003974s