fork download
  1. # https://stackoverflow.com/a/75409015/1468366
  2.  
  3. import collections.abc
  4. import itertools
  5. import math
  6. import typing
  7.  
  8. T = typing.TypeVar('T')
  9. def combination_batches(
  10. seq: collections.abc.Sequence[T],
  11. r: int,
  12. max_batch_size: int,
  13. prefix: tuple[T, ...] = ()
  14. ) -> collections.abc.Iterator[collections.abc.Iterator[tuple[T, ...]]]:
  15. """Compute batches of combinations.
  16.  
  17. Each yielded value is itself a generator over some of the combinations.
  18. Taken together they produce all the combinations.
  19.  
  20. Args:
  21. seq: The sequence of elements to choose from.
  22. r: The number of elements to include in each combination.
  23. max_batch_size: How many elements each returned iterator
  24. is allowed to iterate over.
  25. prefix: Used during recursive calls, prepended to each returned tuple.
  26. Yields: generators which each generate a subset of all the combinations,
  27. in a way that generators together yield every combination exactly once.
  28. """
  29. if math.comb(len(seq), r) > max_batch_size:
  30. # One option: first element taken.
  31. yield from combination_batches(
  32. seq[1:], r - 1, max_batch_size, prefix + (seq[0],))
  33. # Other option: first element not taken.
  34. yield from combination_batches(
  35. seq[1:], r, max_batch_size, prefix)
  36. return
  37. yield (prefix + i for i in itertools.combinations(seq, r))
  38.  
  39. for i in combination_batches("abcdefg", 3, 5):
  40. print("---")
  41. for j in i:
  42. print("".join(j))
  43.  
Success #stdin #stdout 0.04s 9888KB
stdin
Standard input is empty
stdout
---
abc
abd
abe
abf
abg
---
acd
ace
acf
acg
---
ade
adf
adg
---
aef
aeg
afg
---
bcd
bce
bcf
bcg
---
bde
bdf
bdg
---
bef
beg
bfg
---
cde
cdf
cdg
---
cef
ceg
cfg
---
def
deg
dfg
efg