Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: nested 'for' loops

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.

like image 810
098799 Avatar asked Jan 20 '17 13:01

098799


People also ask

What is a nested for loop in Python?

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.

What are nested for loops?

Nested for loops places one for loop inside another for loop. The inner loop is repeated for each iteration of the outer loop.

Can you have a for loop inside a for loop Python?

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.

Can you have nested while loops in Python?

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.


2 Answers

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
like image 164
Stefan Pochmann Avatar answered Sep 19 '22 09:09

Stefan Pochmann


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...

like image 25
hiro protagonist Avatar answered Sep 22 '22 09:09

hiro protagonist