0

this is one of the dumbest questions ever!

I have a for loop:

inner_step = 0
for i, v in enumerate(['a','b'], start=1 if inner_step == 0 else (inner_step+1)):
     print str(i) + ': ' + v
     for k, m in enumerate(['1','2'], start=i+1):
         print str(k) + ': ' + m
         inner_step = k

I hoped for

1: a
2: 1
3: 2
4: b
5: 1
6: 2

but I am getting

1: a
2: 1
3: 2
2: b
3: 1
4: 2

obviously, inner_step is not being overridden by inner loop. what am I doing wrong?

doniyor
  • 36,596
  • 57
  • 175
  • 260
  • If you do some debugging (breakpoint, then inspect the values), the problem will be obvious. – Burhan Khalid Feb 02 '15 at 11:11
  • @BurhanKhalid it would be nice if you could give a hint – doniyor Feb 02 '15 at 11:13
  • 2
    `inner_step` won't change in the outer loop: the enumerate sequence (iterator) is set up at the loop's "initialization". –  Feb 02 '15 at 11:14
  • @Evert so theres no way to continue the outer loop from where the inner loop stopped? – doniyor Feb 02 '15 at 11:16
  • @Evert `inner_step` absolutely does change. That just doesn't affect the iterator the outer loop iterates over. –  Feb 02 '15 at 11:16
  • @delnan how is it then possible to set the ``start`` to the step where the child loop has stopped? is there any other solution for this logic ? – doniyor Feb 02 '15 at 11:19
  • @doniyor Are you looking for debug help or a better way to do it – Bhargav Rao Feb 02 '15 at 11:19
  • 1
    @BhargavRao I just need to achieve this logic, either by fixing it or finding some other way for it – doniyor Feb 02 '15 at 11:20

4 Answers4

2

You can use itertools.count to keep track of the count

from itertools import count

step = count(1)
for v in ['a', 'b']:
    print(str(next(step)) + ': ' + v)
    for m in ['1', '2']:
        print(str(next(step)) + ': ' + m)

1: a
2: 1
3: 2
4: b
5: 1
6: 2
Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321
1

A first step of simplification could be this (although still far away from a pythonic solution):

c = 1
for v in ['a','b']:
    print str(c) + ': ' + v
    c += 1
    for m in ['1','2']:
        print str(c) + ': ' + m
        c += 1
Matt
  • 17,290
  • 7
  • 57
  • 71
1

Your outer loop iterator is not updated after each iteration. The enumerate() object is created just once.

Keep an explicit counter to be updated across the loops:

step = 0
for v in ['a','b']:
     step += 1
     print '{}: {}'.format(step, v)
     for m in['1','2']:
         step += 1
         print '{}: {}'.format(step, m)

or use calculate the numbers from the enumerate numbers:

for outer, v in enumerate(['a','b']):
     print '{}: {}'.format(outer * 3 + 1, v)
     for inner, m in enumerate(['1','2']):
         print '{}: {}'.format(outer * 3 + 2 + inner, m)

Both produce the desired output:

>>> step = 0
>>> for v in ['a','b']:
...      step += 1
...      print '{}: {}'.format(step, v)
...      for m in['1','2']:
...          step += 1
...          print '{}: {}'.format(step, m)
... 
1: a
2: 1
3: 2
4: b
5: 1
6: 2
>>> for outer, v in enumerate(['a','b']):
...      print '{}: {}'.format(outer * 3 + 1, v)
...      for inner, m in enumerate(['1','2']):
...          print '{}: {}'.format(outer * 3 + 2 + inner, m)
... 
1: a
2: 1
3: 2
4: b
5: 1
6: 2
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
1

This seems a good application for a generator. Here the sequence generation code is separated from the enumeration and printing code which makes it possible to reuse the sequence generation code elsewhere.

def expand(seq1, seq2):
    for outer in seq1:
        yield outer
        for inner in seq2:
            yield inner

for i, v in enumerate(expand(['a','b'], ['1','2']), start=1):
    print("{}: {}".format(i, v))

1: a
2: 1
3: 2
4: b
5: 1
6: 2

# or just pass the items to expand() in strings
for i, v in enumerate(expand('abc', '123'), start=1):
    print("{}: {}".format(i, v))

1: a
2: 1
3: 2
4: 3
5: b
6: 1
7: 2
8: 3
9: c
10: 1
11: 2
12: 3

expand() could also be implemented as a normal function that constructs and returns a local list of items from the sequences, however, this generator function is cleaner (no local list required) and more efficient for expanding long sequences.

mhawke
  • 84,695
  • 9
  • 117
  • 138