fork download
  1. # -*- coding: utf-8 -*-
  2. # Python 2.7
  3. '''From here: http://stackoverflow.com/questions/4250125/generate-permutations-of-list-with-repeated-elements
  4. and here: http://b...content-available-to-author-only...n.se/2008/04/lexicographic-permutations-using.html'''
  5.  
  6. def lexicographic_permutations(seq):
  7. '''Algorithm L for The Art of Computer Programming, Volume 4, Fascicle 2: Generating All Tuples and Permutations.'''
  8.  
  9. def reverse(seq, start, end):
  10. '''In-place reversion. Start and end denote the slice ends which forms the chunk to reverse'''
  11. # seq = seq[:start] + reversed(seq[start:end]) + \
  12. # seq[end:]
  13.  
  14. end -= 1
  15. while start < end:
  16. seq[start], seq[end] = seq[end], seq[start]
  17. start += 1
  18. end -= 1
  19.  
  20.  
  21. #Some checks
  22. if not seq:
  23. raise StopIteration
  24.  
  25. try:
  26. seq[0]
  27. except TypeError:
  28. raise TypeError("seq must allow random access.")
  29.  
  30.  
  31. end = len(seq)
  32. seq = seq[:] #copy the input sequence
  33.  
  34. yield seq #return the seq itself as a first value
  35.  
  36.  
  37. while True:
  38. j = end - 1
  39. while True:
  40. # Step 1.
  41. j -= 1
  42. if j == -1:
  43. raise StopIteration
  44. if seq[j] < seq[j+1]:
  45. # Step 2.
  46. l = end - 1
  47. while not seq[j] < seq[l]:
  48. l -= 1
  49. seq[j], seq[l] = seq[l], seq[j]
  50. # Step 3.
  51. reverse(seq, j+1, end)
  52. # Change to yield references to get rid of
  53. # (at worst) |seq|! copy operations.
  54. yield seq[:]
  55. break
  56.  
  57.  
  58. if __name__ == '__main__':
  59. import timeit
  60. #use 'pass' instead of 'print(p)' to get rid of hefty print function time complexity charges.
  61. t = timeit.Timer(stmt='for p in lexicographic_permutations(range(9)): pass',setup='from __main__ import lexicographic_permutations')
  62. print(t.timeit(number=1))
  63.  
  64.  
  65.  
Success #stdin #stdout 1.15s 6740KB
stdin
Standard input is empty
stdout
1.11483001709