[Tutor] Getting range of a list

Dave Angel davea at davea.name
Tue Feb 5 22:39:54 CET 2013


On 02/05/2013 04:08 PM, Hs Hs wrote:
>
>

First comment:  do NOT post in html, as it frequently messes up 
indenting.  Send your email in text mode, as this is a text mailing list.

Compounding that, you apparently are running inside some shell program 
(pyshell ?) which is doing a further mess.  But even if you were running 
under the real interpreter, once you've got doubly nested loops, it gets 
really hard to read.

> Dear List members:
>
> I always have problem in getting ranges:
>
> Following is my representation of part of my file.
>
>> X1
> A
> G
> C
> G
>> X2
> A
> G
>> X3
> A
> G
>> X4
> H
> T
>
>
> I want to print the above contents in the following way:
>
> X1 \t A
> X1 \t G
> X1 \t C
> X1 \t G
> X2 \t A
> X2 \t G
> X3 \t A
> X3 \t G
> X4 \t H
> X4 \t H
>
>
> Here is what I do
>>>> f1 = open('test','r')
>>>> da = f1.read().split('\n')

Why not just use readlines() ?  That's what it's for.

>>>> dat = da[:-1]
>>>> dat

Your shell forgot to display dat here.

>>>> mpos = []
>
>>>> for i in range(len(dat)):
> if dat[i].startswith('>'):
> mpos.append(i)
>
>>>> mpos
> [0, 3, 6, 9]
>
>>>> for item in range(len(mpos)):
> start = mpos[item]
> enda = item+1
> end  = mpos[enda]-1

What is this line intended to do?   enda is too big, so why are you 
surprised it will throw an exception last time through?

> head = dat[start]
> block  = dat[start+1:end]
> for i in block:
> print head+'\t'+i
>
>> X1A
>> X2A
>> X3A
>
> Traceback (most recent call last):
>    File "<pyshell#31>", line 4, in <module>
>      end  = mpos[enda]-1
> IndexError: list index out of range
>>>>
>
>
> By the time I am looping through last item, I do not have anything to take 1 from and thus end up with that indexerror.
>
> Could anyone please help me how to get a good habit of making this work.  This is a very wrong and bad habit.
>
> thank you for your help in advance.
>
> Hs.
>
>
Your mpos list is an index of starting points for records in the dat 
array.  But you're using it also as ending points, and you're missing 
the last one.  The usual way to fix this is to append one more entry to 
mpos, that points just beyond the end of the list dat
    mpos.append(len(dat))

Once you do that,you'll have to change your next for-loop, so it uses 
the original length, perhaps like:
    for item in range(len(mpos))-1:

That should get you closer to working.

However, this whole program feels like it was transliterated from BASIC 
or maybe C.  Any time you have to range(len(...  as the list for a for 
loop, something's probably wrong.  The entire program could be done much 
more elegantly.  And now I can see Steven has posted such an improvement.





-- 
DaveA


More information about the Tutor mailing list