Python中的嵌套while循环

1 投票
4 回答
966 浏览
提问于 2025-04-20 14:57

我正在尝试在一个循环里面再写一个循环,但不知道为什么它没有按预期工作。我知道我可能漏掉了一些很简单的东西,但就是搞不懂问题出在哪里!

这个循环的目的是比较两个字符串,看看它们是否有三个连续的单词是相同的。我首先把这两个字符串分割成各自的三个单词组合,存储在列表strings和stringscompare中。然后,我对strings中的每个三个单词的字符串,循环检查stringscompare中的每个三个单词的字符串。

可能有人觉得这样做有点绕,但我只是个初学者,任何改进建议都非常欢迎。

目前,第二个循环会一直运行到结束,但第一个循环只对strings中的第一个字符串执行了一次。如果字符串匹配,我希望能同时退出这两个循环,但这两个循环还在一个更大的循环里面,我不想退出那个大循环。

例如:

'this is a string'
'this is another string' --没有匹配
'this is a list a strings' --匹配 'this is a'
'the list is a string' --应该匹配 'is a string',但目前没有匹配到

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

4 个回答

0

这里代码最明显的问题是,当内部循环结束后,你没有把X的值重新设为0。我来解释一下:假设'字符串'和'stringscompare'的长度都是3。当你第一次进入外层的while循环时,v=0,x=0。

当我们进入第二个循环时,x=0。离开第二个循环时,如果没有找到匹配的内容,x就变成了字符串比较的长度,也就是3。

现在,当我们回到第一个while循环时,它确实又进入了循环,但什么也不做,因为第二个循环的条件无法满足——X仍然是3!

你可以通过在第二个循环结束时重置X来解决这个问题:

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

你可以通过调试轻松找到像这样的错误。调试有很多方法,真的是一门艺术 :P 我给你一些建议:

  1. 如果你在使用Eclipse、PyCharm等,可以利用内置的调试工具,这些工具非常好用。你可以在程序的任何地方设置断点,查看所有变量的值等等。比如在这个例子中,我会在第一个循环的语句上设置一个断点('while v < len...')。这样,你就能很容易看到第一个循环确实在运行,而问题出在第二个循环。

  2. 打印输出是你的好朋友。比如可以简单地这样做:

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

顺便说一下,你也可以打印变量的值。

其实还有很多其他方法可以实现你想做的事情(比如三角图、先进的搜索方法,或者更复杂的数据结构等等)。但现在,我觉得最好的办法是以最简单的方式解决问题——专注于写出高质量的代码(变量命名要好,缩进、注释等等)。那些高端的、追求性能的技巧可以以后再学 :)

祝你好运,玩得开心!

0

我建议你可以试试这样的做法..

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

在这里用一个 for 循环会更合适。你是想达到这个效果吗?

0

你在代码中用了两次同一个变量 stop。我觉得你应该在循环结束后把 stop 设置为 false:

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
4

你在外层循环里从来没有把 x 重置。这就导致在外层循环的第一次运行后,x 的值总是等于或大于 len(stringscompare)

在外层循环里把它设置为 0

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

其他观察:

不要用 stop == False,用 not stop 就可以了。

你可以直接用一个 for 循环,然后跳出两次:

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

或者用 any() 和生成器表达式来找到第一个匹配项:

 if any(re.search(s, sc) for s in strings for sc in stringscompare):
     same.append(dict)

撰写回答