I'd like to go through all n-digit numbers such that second digit of the number is always lower or equal to the first, third is lower or equal to the second etc. I can get this by writing a horrible code such as:
for i in range(10):
for j in range(i+1):
for k in range(j+1):
etc., but with 10-digit numbers my code starts looking horrible, and also that's a lot of writing, and indentation get horrible if I want to commend few of those. Is there a nice, concise way of getting this?
Edit: just so that people know why I'm bothering with this, https://projecteuler.net/problem=74 has me check numbers from 1 to one milion. Unfortunately, It's not as straightforward as I thought -- numbers with leading zeros are treated differently than the ones with zeros inside, so some additional magic had to be performed. Anyway, thanks to all for insightful suggestions.
Python programming language allows you to use one loop inside another loop. This is known as a nested loop. It is present inside the body of the outer loop. The inner or outer loop can be a for loop or while loop.
Nested for loops places one for loop inside another for loop. The inner loop is repeated for each iteration of the outer loop.
Nested for Loops in Python You can also nest a loop inside another. You can put a for loop inside a while, or a while inside a for, or a for inside a for, or a while inside a while. Or you can put a loop inside a loop inside a loop. You can go as far as you want.
Python While Loop is just another Python statement. As you already know that while loop body can contain statements, we can write while loop inside while loop. While loop inside another while loop is called Nested While Loop.
Could use itertools
:
>>> for comb in itertools.combinations_with_replacement(range(9, -1, -1), 3):
print comb
(9, 9, 9)
(9, 9, 8)
(9, 9, 7)
(9, 9, 6)
...
(4, 0, 0)
(3, 3, 3)
(3, 3, 2)
(3, 3, 1)
(3, 3, 0)
(3, 2, 2)
(3, 2, 1)
(3, 2, 0)
(3, 1, 1)
(3, 1, 0)
(3, 0, 0)
(2, 2, 2)
(2, 2, 1)
(2, 2, 0)
(2, 1, 1)
(2, 1, 0)
(2, 0, 0)
(1, 1, 1)
(1, 1, 0)
(1, 0, 0)
(0, 0, 0)
Or recursively, appending more and more digits until enough, which can more directly produce int
objects instead of digit tuples (not sure whether that's what you actually need):
def build(enough, prefix=0):
if prefix >= enough:
print(prefix)
return
for digit in range(prefix % 10 + 1) if prefix else range(1, 10):
build(enough, prefix * 10 + digit)
Demo (note it leaves out "000
", not sure whether you'd want that anyway):
>>> n = 3
>>> build(10**(n-1))
100
110
111
200
210
211
220
221
222
300
310
311
320
321
322
330
331
332
333
400
410
411
420
this an approach using itertools
:
from itertools import combinations_with_replacement
N = 3
for kji in combinations_with_replacement((str(i) for i in range(10)), N):
print(''.join(reversed(kji)))
note that the order is not the same as in your original approach.
i recently had a simliar question...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With