python 中的 If 语句仅通过改变条件的位置而工作不同
If statement in python working different just by changing position of condition
我刚刚在python遇到了一个奇怪的问题:
下面是合并排序算法的一个实现,如果我尝试 运行 它会给我一个索引错误。
def mergesort(s1,s2,S):
i,j = 0,0
while i+j < len(s1)+len(s2):
if (i < len(s1) and s1[i] < s2[j]) or j == len(s2):
S.append(s1[i])
i += 1
else:
S.append(s2[j])
j += 1
return S
s2 = [1,5,7]
s1 = [2,3,4,6,8]
S = []
print(mergesort(s1,s2,S))
这个程序的输出是:
Traceback (most recent call last):
File "new.py", line 15, in <module>
print(mergesort(s1,s2,S))
File "new.py", line 4, in mergesort
if (i < len(s1) and s1[i] < s2[j]) or j == len(s2):
IndexError: list index out of range
现在只需在 if
语句中键入 j == len(s2)
,程序 运行 就完全没问题了:
def mergesort(s1,s2,S):
i,j = 0,0
while i+j < len(s1)+len(s2):
if j == len(s2) or (i < len(s1) and s1[i] < s2[j]):
S.append(s1[i])
i += 1
else:
S.append(s2[j])
j += 1
return S
s2 = [1,5,7]
s1 = [2,3,4,6,8]
S = []
print(mergesort(s1,s2,S))
输出:[1, 2, 3, 4, 5, 6, 7, 8]
这真的让我感到惊讶,因为两个程序完全相同,但前一个给我一个错误。
此外,有问题的程序 运行 在 c++ 中没问题:
#include <iostream>
using namespace std;
int main() {
int s1[10] = { 2, 3, 4, 6, 8 }, s2[10] = { 1, 5, 7 }, s[20], i = 0, j = 0, x = 0;
while (i + j < 8) {
if ((i < 5 && s1[i] < s2[j]) || j == 3) {
s[x++] = s1[i];
i++;
} else {
s[x++] = s2[j];
j++;
}
}
for (int i = 0; i < 8; i++) {
cout << s[i];
}
return 0;
}
输出:12345678
为什么在 python 运行 中给我错误的程序在 C++ 中完全正常?
python 的 if
语句与 c++ 的 if
语句的工作方式不同吗?
第一个python程序确实不正确:如果j
达到s2
的长度,if (i < len(s1) and s1[i] < s2[j]) or j == len(s2):
将导致越界访问s2[j]
在 i
到达 s1
的末尾之前。
修复方法是在 (i < len(s1) and s1[i] < s2[j])
之前测试 j == len(s2)
(i < len(s1) and s1[i] < s2[j])
,因为您自己已经正确地找到了。
C++程序有同样的问题,但C++不检测越界访问。阅读 s2[3]
只是具有未定义的行为,在您的情况下只是 returns 一个未指定的值。由于 j == 3
,该测试无论如何都会评估为真,因此算法输出预期结果。
未定义的行为有时会产生预期的结果而不会引起注意。但是在较大的分配数组上使用该算法可能会产生明显的副作用,例如分段错误。
我刚刚在python遇到了一个奇怪的问题: 下面是合并排序算法的一个实现,如果我尝试 运行 它会给我一个索引错误。
def mergesort(s1,s2,S):
i,j = 0,0
while i+j < len(s1)+len(s2):
if (i < len(s1) and s1[i] < s2[j]) or j == len(s2):
S.append(s1[i])
i += 1
else:
S.append(s2[j])
j += 1
return S
s2 = [1,5,7]
s1 = [2,3,4,6,8]
S = []
print(mergesort(s1,s2,S))
这个程序的输出是:
Traceback (most recent call last):
File "new.py", line 15, in <module>
print(mergesort(s1,s2,S))
File "new.py", line 4, in mergesort
if (i < len(s1) and s1[i] < s2[j]) or j == len(s2):
IndexError: list index out of range
现在只需在 if
语句中键入 j == len(s2)
,程序 运行 就完全没问题了:
def mergesort(s1,s2,S):
i,j = 0,0
while i+j < len(s1)+len(s2):
if j == len(s2) or (i < len(s1) and s1[i] < s2[j]):
S.append(s1[i])
i += 1
else:
S.append(s2[j])
j += 1
return S
s2 = [1,5,7]
s1 = [2,3,4,6,8]
S = []
print(mergesort(s1,s2,S))
输出:[1, 2, 3, 4, 5, 6, 7, 8]
这真的让我感到惊讶,因为两个程序完全相同,但前一个给我一个错误。
此外,有问题的程序 运行 在 c++ 中没问题:
#include <iostream>
using namespace std;
int main() {
int s1[10] = { 2, 3, 4, 6, 8 }, s2[10] = { 1, 5, 7 }, s[20], i = 0, j = 0, x = 0;
while (i + j < 8) {
if ((i < 5 && s1[i] < s2[j]) || j == 3) {
s[x++] = s1[i];
i++;
} else {
s[x++] = s2[j];
j++;
}
}
for (int i = 0; i < 8; i++) {
cout << s[i];
}
return 0;
}
输出:12345678
为什么在 python 运行 中给我错误的程序在 C++ 中完全正常?
python 的 if
语句与 c++ 的 if
语句的工作方式不同吗?
第一个python程序确实不正确:如果j
达到s2
的长度,if (i < len(s1) and s1[i] < s2[j]) or j == len(s2):
将导致越界访问s2[j]
在 i
到达 s1
的末尾之前。
修复方法是在 (i < len(s1) and s1[i] < s2[j])
之前测试 j == len(s2)
(i < len(s1) and s1[i] < s2[j])
,因为您自己已经正确地找到了。
C++程序有同样的问题,但C++不检测越界访问。阅读 s2[3]
只是具有未定义的行为,在您的情况下只是 returns 一个未指定的值。由于 j == 3
,该测试无论如何都会评估为真,因此算法输出预期结果。
未定义的行为有时会产生预期的结果而不会引起注意。但是在较大的分配数组上使用该算法可能会产生明显的副作用,例如分段错误。