1

I am trying to write a while-loop within a while-loop, and for some reason it is not working as it should. I know I'm probably missing something really trivial here, but I just don't understand how its not working!

The purpose of the loop is to compare two strings to see whether or not they contain any 3 consecutive words the same. I first split the two strings into lists of their respective 3 word string combinations which I store in the lists strings and stringscompare. Then I loop through each 3 word string in stringscompare for each 3 word string in strings.

This will probably seem like a pretty long way round for some but I am only a novice programmer, any improvements would be greatly appreciated.

So currently, the second while loop runs all the way through, however the first one only loops through once, for the first string in strings. If the string matches I would like it to break from both loops, however these loops are also in a much bigger for loop which I don't want it to break out of.

e.g.

'this is a string'
'this is another string' --no match
'this is a list a strings' -- matches 'this is a'
'the list is a string' -- should match 'is a string' but currently does not

strings = <list of 3 word strings> [...,...,...]
stringscompare = <list of 3 word strings to compare>
v=0, x=0
while v < len(strings) and stop == False:
    while x < len(stringscompare) and stop == False:
        if re.search(strings[v], stringscompare[x]):
            same.append(dict)
            stop = True
        x += 1
    v +=1
1
  • Without concrete examples of strings and stringscompare hard to tell what's going wrong here, but my guess would be that in the inner loop, stop gets set to be True, therefore the outer loop terminates. Are you sure the condition and stop == False in the outer loop is intended? Commented Sep 9, 2014 at 9:19

4 Answers 4

4

You never reset x inside the outer loop. As a result it'll always be equal or greater to len(stringscompare) after the first iteration of the outer loop.

Set it to 0 in the outer loop:

v = 0
while v < len(strings) and stop == False:
    x = 0
    while x < len(stringscompare) and stop == False:

Other observations:

Don't use stop == False where not stop will do.

You could just use a for loop, then break out twice:

for s in strings:
    for sc in stringscompare:
        if re.search(s, sc):
            same.append(dict)
            break
    else:
        continue
    # only reached if the inner loop broke out
    break

or use any() with a generator expression to find the first match:

 if any(re.search(s, sc) for s in strings for sc in stringscompare):
     same.append(dict)
Sign up to request clarification or add additional context in comments.

3 Comments

Awesome!! Thank you so much, I've been looking at this for hours and I knew it would be something stupidly simple!!!
And thank you for your observations, your way is much more elegant!!
@LauraQuinn: glad you found more than one answer to be helpful! Do take into account you can only award one of the answers with the 15 points. If you knew this and found Matanoga's answer to be more helpful, then congratulations go to him. :-)
0

you use twice the same variable stop I think you should set the stop to false after the loop:

strings = <list of 3 word strings> [...,...,...]
stringscompare = <list of 3 word strings to compare>
v=0, x=0
while v < len(strings) and stop == False:
    while x < len(stringscompare) and stop == False:
        if re.search(strings[v], stringscompare[x]):
            same.append(dict)
            stop = True
        x += 1
    stop = False
    v +=1

Comments

0

I would suggest something like this..

strings = [] # <list of 3 word strings> [...,...,...]
stringscompare = [] # <list of 3 word strings to compare>

stop = False

for x in strings:
    if stop:
        break

    for v in stringscompare:
        if re.search(v, x):
            stop = True
            break

A for loop seems a lot more appropriate here. Is this what you're trying to achieve?

Comments

0

Well the most obvious problem with the code here is that you do not set the value of X to be 0 again once the inner loop finishes. I'll explain: Lets say both 'strings' and 'stringscompare' length is 3. When you first enter the big while loop, v=0 and x=0. When we enter the second loop, x=0. When we leave the second loop, if no match was found, x = length(stringscompare) = 3.

Now, when we go back to the first while loop it DOES actually go inside the loop again - but it does nothing, as the clause for the 2nd loop cannot be satisfied - X is still 3!

You can fix this by resetting X at the end of loop 2:

strings = <list of 3 word strings> [...,...,...]
stringscompare = <list of 3 word strings to compare>
v=0, x=0
while v < len(strings) and stop == False:
    while x < len(stringscompare) and stop == False:
        if re.search(strings[v], stringscompare[x]):
            same.append(dict)
            stop = True
        x += 1
    x = 0 #resetting X
    v +=1

You can easily track downs problems like this one by debugging. There are many methods to debugging, its an art really :P What I would recommend for you:

  1. If your'e using Eclipse, PyCharm, etc, you can use the built in debuggers which are amazing. You can stop at any point of the program by adding breakpoints, see the value of all the variables, etc. For example, in this case, I would put a breakpoint on the first loop statement ('while v < len...'). That way, you couldv easly see that the first loop is in fact running, and its the second loop thats the problem.

  2. Printing is your friend. Something simple like this for example:

v=0, x=0 
while v < len(strings) and stop == False:
  print "About to enter second loop..."
  while x < len(stringscompare) and stop == False:
      if re.search(strings[v], stringscompare[x]):
          same.append(dict)
          stop = True
      x += 1
  v +=1

You could also print the values of variables btw.

There are many other ways to do what you're trying to do (triangle graphs, advanced search methods, maybe a more complex data structure, etc). But for now - I think the best thing for you is to solve problems in the most straightforward way you can - focus on writing quality code (well named variables, indents, comments etc). The geeky, 'top performance' cutting edge tricks will come in later :)

Good luck and have fun!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.