0

I have state_array function. If if state ist true, i'm deleting item from list result. It's not working because for-loop ist out of range. I wat to fix it, and want to ask, it is possible to have list comprehension instead of 'for-loop', if yes, how to do that ?

def state_array(self):
    for k in range(len(result)):
        if '[0]' in str(result[k]):
            if '[7]' in str(result[k+7]) and '[8]' not in str(result[k+8]):
                result[k][0] = str(result[k][0]).replace('[0]', '').replace('X0', 'X0,8')                      # state array
                del result[k+1:k+7]
            else:
                continue

My input:

V;3;M_BB01_03[0];SPPP.BK1800.58,X0;RW
V;3;M_BB01_03[1];SPPP.BK1800.58,X1;RW
V;3;M_BB01_03[2];SPPP.BK1800.58,X2;RW
V;3;M_BB01_03[3];SPPP.BK1800.58,X3;RW
V;3;M_BB01_03[4];SPPP.BK1800.58,X4;RW
V;3;M_BB01_03[5];SPPP.BK1800.58,X5;RW
V;3;M_BB01_03[6];SPPP.BK1800.58,X6;RW
V;3;M_BB01_03[7];SPPP.BK1800.58,X7;RW

And expected output:

V;3;M_BB01_03[0];SPPP.BK1800.58,X0,8;RW
Luk
  • 185
  • 1
  • 2
  • 10
  • Can you give some input and expected output? If you give a code snippet that can be run completely on its own, it's a lot easier for people to help you – Kewl Apr 11 '17 at 13:21
  • 1
    Duplicate of [remove items from a list while iterating](http://stackoverflow.com/questions/1207406/remove-items-from-a-list-while-iterating) – SiHa Apr 11 '17 at 13:25
  • I updated question on input and output – Luk Apr 11 '17 at 13:28
  • Is your input a list of strings? – Chuck Apr 11 '17 at 13:45
  • Why do you check the 9th element when your input string has only 8 elements? – Chuck Apr 11 '17 at 13:55
  • Yes, my input ist list of strings. I'm checking the 9th element, because i what to do this function only for 8 bits array. – Luk Apr 11 '17 at 14:34

2 Answers2

1

Here you have too much logic in this block in order to do a clean list comprehension. I do not say it is impossible to pack it all in a list comprehension, i say it would be badly ugly. To prevent your out of range error, just replace range(len(result)) by enumerate(result).

def state_array(self):
for k, r in enumerate(result):
    if k+7 >= len(result):
        break
    if '[0]' in str(r):
        if '[7]' in str(result[k+7]) and '[8]' not in str(result[k+8]):
            r[0] = str(r[0]).replace('[0]', '').replace('X0', 'X0,8')                      # state array
            del result[k+1:k+7]
        else:
            continue
  • It does resolve it because instead of iterating over a fixed sized range created prior to the loop, you are iterating over the actual items. The only thing i forgot is to check if k+7 is inferior to the length of results. – Arnaud De Broissia Apr 11 '17 at 13:53
  • So, if you use `enumerate` which yields an iterator, you don't get an IndexError if the size of the iterable changes! I didn't know that - thanks. – SiHa Apr 11 '17 at 14:04
  • It's not working, i have an error: `if int(k+7) >= len(result): TypeError: can only concatenate list (not "int") to list` – Luk Apr 11 '17 at 14:30
  • my bad, it's k, r in enumerate(result) – Arnaud De Broissia Apr 11 '17 at 14:34
1

You loop from 0 to the original length of the array, but then you change the actual length within the loop. A quickfix to this is to use a while loop:

k=0
while(k<len(A)):
    if(condition)
         del(A[k])
    k=k+1
klutt
  • 30,332
  • 17
  • 55
  • 95