[Tutor] Fwd: Re: Loop in pre-defined blocks

Peter Otten __peter__ at web.de
Sat Jun 11 03:49:48 EDT 2016


Alan Gauld via Tutor wrote:

> Forwarding to tutor list. Always use Reply All when responding to list
> mail.
> 
>> Sorry, to be a little bit more descriptive. I'd like to loop from 1 to 35
>> but within this loop there are divisions which I need to prefix that
>> particular division number.
> 
>> My output would look like this:
>>>>>>>>>>>>>>>>
> 1 1
> 1 2
> 1 3
> 1 4
> 1 5
> 1 6
> 1 7
> 1 8
> 1 9
> 1 10
> 1 11
> 1 12
> 2 13
> 2 14
> 2 15
> 2 16
> 2 17
> 2 18
> 2 19
> 2 20
> 3 25
> 3 26
> 3 27
> 3 28
> 3 29
> 3 30
> 3 31
> 3 32
> 3 33
> 3 34
> 3 35
>>>>>>>>>>>>>>>>
> 
> You can't specify the blocks as just (12,20,.35) since you are using
> non-contiguous blocks - you have a gap between 20 and 25.
> 
> So your definition needs to be (1,12),(13,20),(25,35) to specify
> the missing rows. But you can arguably simplify the code a little:
> 
> blocks = ((1,13),(13,21),(25,36))
> for prefix, block in enumerate(blocks):
>      for n in range(*block):
>           print prefix+1, n
> 
> its very similar to your code but using tuple expansion in range()
> cleans it up a little bit and the names hopefully make the intent
> clearer.

As Alan says, you need to specify the gaps. A simple if hackish way is to 
use negative numbers:

def expand(ends):
    start = 1
    for end in ends:
        if end < 0:
            start = -end
        else:
            end += 1
            yield (start, end)
            start = end

blocks = [12, 20, -25, 35]
for index, span in enumerate(expand(blocks), 1):
    for x in xrange(*span):
        print index, x




More information about the Tutor mailing list