2

I have this piece of code that will generate all combinations of a 3-digit number

for n1 in range(10):
    for n2 in range(10):
        for n3 in range(10):
            print(n1,n2,n3)

input()

so this will generate 001,002,003... all the way to 999 and this works fine, my question is how do I extend this code to run with a custom amount of digits that I can input? For example, if I say 5, it should run 5 for loops and print all the results in order to get 00001,00002... 99999. So how do I dynamically create more for loops without writing them myself?

BlockCoder
  • 135
  • 2
  • 12
  • 2
    You should look into itertools [combinations](https://docs.python.org/3.6/library/itertools.html#itertools.combinations) – DoughnutDayDevotee Jan 06 '19 at 02:22
  • 1
    for digits it's better to just run from 1 to 10^n-1 instead of using n separate loops – phuclv Jan 06 '19 at 02:25
  • @DoughnutDayDevotee: combinations seems to have a problem here. The OP doesn't want all the combinations. OP just wants all the numbers starting from 0 up to n (like `range(n)`) but printed in a certain width. See my comments on U9-Forward's answer and check my answer too. You will see what I mean – Sheldore Jan 06 '19 at 02:43
  • Neither will `combinations_with_replacement ` work for this problem. `product` is however working although it is slow as compared to simply loop over the range and `format` – Sheldore Jan 06 '19 at 02:49

5 Answers5

4

You can use recursion

def func(n, k, *args):
  if n:
    for i in range(k):
      func(n - 1, k, *args, i)
  else:
    print(*args)

func(3, 10)
JoshuaCS
  • 2,524
  • 1
  • 13
  • 16
3

Use product of the itertools module:

from itertools import product
for i in product(range(10),repeat=5):
    print(*i,sep='')

Much faster:

from itertools import product
l = list(product(range(10),repeat=5))
print('\n'.join([''.join(map(str,i)) for i in l]))
U13-Forward
  • 69,221
  • 14
  • 89
  • 114
2

You can use format to make your code independent of the maximum number to be printed. Using a direct for loop over the range seems to be quite efficient as compared to the product module from collections because for each combination, it calculates the product.

max_num = 1000
width=len(str(max_num))

for n1 in range(1, max_num):
    print ('{n1:0{width}}'.format(n1=n1, width=width))

Output

0001
0002
0003
.
.
.
0998
0999
Sheldore
  • 37,862
  • 7
  • 57
  • 71
0

You need not to create multiple loops, it can be accomplished by single loop only.

digits = int(input("Enter the number of digits you want: "))

for i in range(1, 10 ** digits):
    print('{num:0{width}}'.format(num=i, width=digits))

With this you can generate as many numbers required for as many digits. Limited by the size of type integer.

  • Your `digits` is redundant. It should be calculated from `numbers`. – Sheldore Jan 06 '19 at 02:46
  • In question @BlockCoder asked: "my question is how do I extend this code to run with a custom amount of digits that I can input?". Hence, here the user will input the custom amount of digits. – Anidhya Bhatnagar Jan 06 '19 at 02:48
  • No, read this line "For example, if I say 5, it should run 5 for loops and print all the results in order to get 00001,00002... 99999". Here 5 means also range(10**5) and also the digits. So I believe both numbers go hand in hand. Choosing n=3 and printing up to 99999 makes no sense because you can't print 99999 (and other 4 and 5 and higher digit numbers) in 3 width. Do you see my point? – Sheldore Jan 06 '19 at 02:51
  • Yes I got it, here @DariusMorawiec power will do good. Updating my answer with that. – Anidhya Bhatnagar Jan 06 '19 at 02:54
0

In general I like the approach of @Bazingaa, but I prefer the combination of power and zfill:

def func(digits):
    for n in range(1, 10 ** digits):
        print(str(n).zfill(digits))

func(3)

# 001
# 002
# 003
# ...
# 997
# 998
# 999
Darius
  • 10,762
  • 2
  • 29
  • 50