1

I'm trying to get all combinations of numbers but it's a bit complex, so I'll show via example:

Say I have a list like [5, 10, 12, 4, 6] I want the combinations of [1, 1, 1, 1, 1], [1, 2, 1, 1, 1], ... [5, 10, 12, 4, 6]

So each number only goes up to it's highest point. I've tried this:

def listdir_nohidden(path):
  for f in os.listdir(path):
    if not f.startswith('.'):
      yield f

def listdir(path):
  return list(listdir_nohidden(path))

def listlen(path):
  return len(list(listdir_nohidden(path)))

def randomiser(filename):
  return random.randint(1,listlen(f'./{filename}'))

lengths = []
i = 0
while i < 5:
  lengths.append(listlen(f'./{i}'))
  i += 1
print(lengths) # ['5', '16', '16', '16', '6']

random_array = []
j = 0
while j < 30:
  random_array.append([randomiser(0), randomiser(1), randomiser(2), randomiser(3), randomiser(4)])
  j += 1

But there is a chance for duplicates and it's not truly random. I know with the numbers in the list high enough the chances are really slim, but I actually want to generate lots of these so the chance of a duplicate goes up.

  • Yours is not an optimal solution, but as a quick fix you can make `random_array` a `set` so that there are no duplicates. In that case you will also have to `.add` a `tuple` to it instead of a `list` as `list`s can not be set elements as they are not hashable. – Selcuk Jan 12 '22 at 02:11
  • Could you elaborate what you mean by "all combinations of numbers"? Without further context, 'all combinations of numbers' is an infinitely large set. – Ewan Brown Jan 12 '22 at 02:11

1 Answers1

2

How about using itertools.product?

import itertools

lst = [5, 10, 12, 4, 6]

output = list(itertools.product(*(range(1, k+1) for k in lst)))
print(output[:5]) # first five: [(1, 1, 1, 1, 1), (1, 1, 1, 1, 2), (1, 1, 1, 1, 3), (1, 1, 1, 1, 4), (1, 1, 1, 1, 5)]
print(output[-5:]) # last five: [(5, 10, 12, 4, 2), (5, 10, 12, 4, 3), (5, 10, 12, 4, 4), (5, 10, 12, 4, 5), (5, 10, 12, 4, 6)]
j1-lee
  • 13,764
  • 3
  • 14
  • 26