简体   繁体   中英

while infinite loop after 2 loops

I basically want to put each letter to a different list so that the first letter goes in the first list until the kth letter. Then the k+1th letter should go in the k-1th list and the next to the k-2th list etc. The fact is that after the second loop the while enters in an infinite loop

def f(s,k):      
 l = [[] for i in range(k)]
 i = 0
 while i < len(s):
   for j in range(0,k):
     l[j].append(s[i])
     print(l)
     i += 1
   for k in range(k-2,-1,-1):
     l[k].append(s[i])
     print(l)
     i += 1
 return l

Don't use the same variable k for the second iteration variable and your function parameter. When the second loop is done, k will be set to 0 . The next iteration of the while loop will then do for j in range(0, 0): , which doesn't do anything, followed by for k in range(-2, -1, -1): , which also doesn't do anything. So i never gets incremented any more, and you get stuck in the infinite loop.

Change for k to for m and you won't get the infinite loop. But you'll get an IndexError when accessing s[i] if len(s) is not a multiple of 2 * k - 1 .

It would be better to iterate over the characters in s .

def f(s,k):      
    l = [[] for i in range(k)]
    i = 0
    inc = 1
    for c in s:
        l[i].append(c)
        i += inc
        # Check if we need to reverse direction
        if inc == 1 and i == k:
            inc = -1
            i = k - 2
        elif inc == -1 and i == -1:
            inc = 1
            i = 0
    return l

As @Barmar already stated, the reason why your algorithm does not work are the for -loops. So you effectively skip the first letter, at least. Also the usage of k is problematic. However his proposed algorithm doesn't work like you want it to work, though. In the end this is what @Barmar had in mind:

def f(string, k):
    result = [[] for _ in range(k)]
    bin_index = -1
    inc = 1
    for i in range(len(string)):
        bin_index += inc
        # reverse by setting the bin_index and changing the increment-step
        if bin_index == k:
            bin_index = (k - 1) - 1
            inc = -1
        # going forward again
        if bin_index == 0 and i != 0:
            inc = 1
        result[bin_index].append(string[i])

    return result

@Barmar : You have a bug in your program when i returns from the back-pass. It will not be set to another bin-index so that always the character on index k+1 and k+2 (or multiples of them) will be in the same bin (the first list). But they should be in two different bins. So this would get rid of the bug:

def f(s, k):
    l = [[] for i in range(k)]
    i = 0
    inc = 1
    for c in s:
        l[i].append(c)
        i += inc
        # Check if we need to reverse direction
        if inc == 1 and i == k:
            inc = -1
            i = k - 2
        elif inc == -1 and i == -1:
            inc = 1
            i = 1 # this should be 1 not 0
    return l

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM