Home > OS >  Problem handling next elements in for-loop Python
Problem handling next elements in for-loop Python

Time:08-29

I have my res_list of string that looks like this

Sleep Morning_Meds 2
Morning_Meds Watch_TV 1
Watch_TV Sleep 3
Morning_Meds Sleep 1
Sleep Watch_TV 3

I know it's a simple task but I'm struggling doing it, what I need to achive is something like this:

Morning_Meds Watch_TV, Sleep 1
Watch_TV Sleep 3
Sleep Watch_TV 3

the logic is that I want to be left in the list the ones with higher value: for example, in the first block with my initial list there are "Sleep Morning_Meds 2" and "Sleep Watch_TV 3", in the second block it only remains "Sleep Watch_TV 3" because 3 is higher than 2. In case the value is equal to the other one like "Morning_Meds Watch_TV 1" "Morning_Meds Sleep 1" I want to create a new string including both "Watch_TV" and "Sleep".

What I tried doing is this:

for g in range(0, len(res_list) - 1):
    v = res_list[g].split()  # taking the first element and splitting it because it's a string
    for j in range(g   1, len(res_list)):  # i'm beginning from the element next g 
        v1 = res_list[j].split()  # also splitting it 
        if v[0] == v1[0]:  #  if the first name is equal to the next one...
            if v[2] < v1[2]:  # ...checking what value is higher...
                res_list.remove(res_list[g])  #...and then removing the lowest of the two
            elif v[2] == v1[2]:  # checking if the values are equals 
                new_element= v[0]   " "   v[1]   ", "   v1[1]   " "   v[2]
                res_list.insert(j, new_element)  # adding the new string
                res_list.remove(res_list[g])  # removing the old ones
                res_list.remove(res_list[j])
            else:  # checking if the first value is higher than the next one 
                res_list.remove(res_list[j])

the problem here is that if I trubleshoot printing it only compare the first string "Sleep Morning_Meds 2" with "Sleep Watch_TV 3", it doesn't consider the other ones and I don't know why:

Morning_Meds Watch_TV 1
Watch_TV Sleep 3
Morning_Meds Sleep 1
Sleep Watch_TV 3

how can I do it? Thanks!

CodePudding user response:

The reason why it doesn't work, is because your index shifts when you remove something from the list. For example:

a = [1,2,3,4,5,6,7,8,9,10]

for i in range(len(a)):
    print(a[i])
    a.remove(a[0])

What has the output:

1
3
5
7
9
out of range error

Since your start value in the inner loop (the second loop), gets higher than the length of the list it immediately finishes causing the rest of the code to be skipped. (that is why you don't see an out of range error as you never use the shifted index to access the list)

simplified example of that:

a = [1,2,3,4]

for i in range(len(a)):
    print("i: ",i)
    for j in range(i 1,len(a)):
        a[j] #doesnt crash
        print(" j: ",j)
    a.remove(a[0])

what gives the output:

i:  0
 j:  1
 j:  2
 j:  3
i:  1
 j:  2
i:  2
i:  3

The code below should work.

res_list = ["Sleep Morning_Meds 2",
"Morning_Meds Watch_TV 1",
"Watch_TV Sleep 3",
"Morning_Meds Sleep 1",
"Sleep Watch_TV 3"]

done = False 
while(not done):

    flag = False #double loop break flag
    for v_index in range(0, len(res_list)):
        v = res_list[v_index].split(" ")
        for v1_index in range(v_index   1, len(res_list)):
            v1 = res_list[v1_index].split(" ")

            if(v[0] == v1[0]):
                if(v[2] > v1[2]):
                    res_list.remove(res_list[v1_index]) #remove v1
                    flag = True
                    break 
                
                elif(v[2] < v1[2]):
                    res_list.remove(res_list[v_index]) #remove v 
                    flag = True
                    break

                else:#equal
                    new_element= v[0]   " "   v[1]   ", "   v1[1]   " "   v[2]
                    res_list.append(new_element)

                    if(v_index > v1_index):#correcting for index shift (remove highest index first)
                        res_list.remove(res_list[v_index])
                        res_list.remove(res_list[v1_index])

                    else:
                        res_list.remove(res_list[v1_index])
                        res_list.remove(res_list[v_index])

                    flag = True
                    break

        if(flag):
            break
    if(not flag):
        done = True 


print(res_list)

output:

['Watch_TV Sleep 3', 'Sleep Watch_TV 3', 'Morning_Meds Watch_TV, Sleep 1']
  • Related