为什么这个while循环不起作用?

时间:2017-07-09 03:41:34

标签: python python-3.x while-loop

谢谢大家!我改变了我的代码,它仍然给出了错误:

  

列出索引超出范围。

为什么?

M  = []
B = [1, 3, 5]
C = [2, 4, 6]
while (B and C):
    if B[0] <= C[0]: 
        M.append(B.pop(0))
    if C[0] <= B[0]: 
        M.append(C.pop(0))

print('Updated list: ', M)

`

6 个答案:

答案 0 :(得分:0)

B和C汇合到:

B = [4, 5]
C = [2, 3, 6]

C[0](2)显然不大于或等于B[0](4)

所以弹出B的分支不会被击中,而你会陷入无限循环

答案 1 :(得分:0)

在你的while循环中,你在B和C上使用了和运算符。根据Python 2.7的参考5.1,只有空数组会产生False。

https://docs.python.org/release/2.7.13/library/stdtypes.html#truth-value-testing

正如Mark所建议的,在第一次弹出之后,条件B [0]&lt; = C [0]不再为真,因此不再弹出元素。反过来,这意味着B或C都不会达到空的点。因此,不可能退出此循环。

答案 2 :(得分:0)

错在哪里: 执行B.pop(0)后第三次执行while循环时,列表​​B变为空。因此,当列表B[0]已空时,当您在下一行调用B时,您会收到错误IndexError: list index out of range

使用Print Statement解释:

我在你的代码中添加了一些打印语句

M  = []
B = [1, 3, 5]
C = [2, 4, 6]
while (B and C):
    print("==============")
    if B[0] <= C[0]: 
        M.append(B.pop(0))
    print("B: " + str(B))
    if C[0] <= B[0]: 
        M.append(C.pop(0))
    print("C: " + str(C))

我得到的结果是:

==============
B: [3, 5]
C: [4, 6]
==============
B: [5]
C: [6]
==============
B: []
Traceback (most recent call last):
  File "python", line 9, in <module>
IndexError: list index out of range

B已空时,您无法拨打B[0]。当您尝试从list[x]的列表中获取元素时。 x必须介于0和列表大小之间 - 1。

<强>建议: 我强烈建议您学习如何使用print to debug your code。这非常有用。特别是像Python这样的过程语言。

答案 3 :(得分:0)

您可以通过打印进行调试,以观察代码中发生的情况:

Before Popping: 
======================================
B and C:  [2, 4, 6]
B:  [1, 3, 5]
C:  [2, 4, 6]
======================================
Enters B[0] <= C[0] since 1 <= 2
B[0] = "1" is popped out

New value for B and C: 
B:  [3, 5]
C:  [2, 4, 6]

======================================
Enters C[0] <= B[0] since 2 <= 3
C[0] = "2" is popped out

New value for B and C: 
B:  [3, 5]
C:  [4, 6]

After Popping: 
*****************************************
B and C:  [4, 6]
B:  [3, 5]
C:  [4, 6]
*****************************************
Before Popping: 
======================================
B and C:  [4, 6]
B:  [3, 5]
C:  [4, 6]
======================================
Enters B[0] <= C[0] since 3 <= 4
B[0] = "3" is popped out

New value for B and C: 
B:  [5]
C:  [4, 6]

======================================
Enters C[0] <= B[0] since 4 <= 5
C[0] = "4" is popped out

New value for B and C: 
B:  [5]
C:  [6]

After Popping: 
*****************************************
B and C:  [6]
B:  [5]
C:  [6]
*****************************************
Before Popping: 
======================================
B and C:  [6]
B:  [5]
C:  [6]
======================================
Enters B[0] <= C[0] since 5 <= 6
B[0] = "5" is popped out

New value for B and C: 
B:  []
C:  [6]

======================================

最后,它得到IndexError: list index out of range,因为B[]

答案 4 :(得分:0)

因为最终你最终会在代码中的某个位置结束,其中一个列表为空 - 所以它没有索引0来引用。具体来说,列表中的5个B是该列表的最后一个元素&#39;消费&#39; - 复制到M并从B删除,之后列表没有索引0。

我认为有两种解决方法:

下面的第一个解决方案可以解决您的问题,在这个问题中,您不会在while循环开始时存在BC来触发B and C返回False并让您脱离循环。最后,在B[0] <= C[0]中,B中的5被删除,代码移到C[0] <= B[0]旁边,因此错误,因为{ {1}}为空。代码的功能相同,如果B代码的那部分运行,如果没有(在这种情况下B[0] <= C[0]为真),则执行原始第二个C[0] <= B[0]语句中的代码而不执行测试这种情况。

这意味着if循环运行的次数更多,因为它每个循环只执行一次操作,但这意味着它在每次更改列表后都会测试while,从而避免尝试执行操作在空列表索引上,如果while (B and C)B为空,则评估为false,并且while循环将退出。

C

我提出的第二个解决方案(我首先提出,虽然更明确,但不那么简单)是明确指出M = [] B = [1, 3, 5] C = [2, 4, 6] while (B and C): if B[0] <= C[0]: M.append(B.pop(0)) else: M.append(C.pop(0)) print('Updated list: ', M) B都需要包含一些内容(即必须有一个索引0)在运行原始代码中的每个C语句之前,如果其中任何一个为空,则在引发错误的if语句之前中断while循环可以运行:

if

您可以在M = [] B = [1, 3, 5] C = [2, 4, 6] while (B and C): if len(B) == 0 or len(C) == 0: break if B[0] <= C[0]: M.append(B.pop(0)) if len(B) == 0 or len(C) == 0: break if C[0] <= B[0]: M.append(C.pop(0)) print('Updated list: ', M) 循环之后和while函数之前添加此代码,以确保所有列表项都添加到print

M

基本上,这只是将列表中的空列表添加到一个项目中,新列表D = B+C M.append(D.pop(0)) 在索引0处包含单个项目,然后将其附加到D

答案 5 :(得分:0)

将您的第二个if重置为elif