python range 的“坑”

请实现一个函数,其功能为检查List中是否含有数字6。代码很简单,可能有人会这样写:

def check(arr):
	for i in range(len(arr)):
		if arr[i] == 6:
			appear = True
			break
	if i == len(arr): appear = False
	print("6 appears in arr? ", appear)

上述代码很简单,如果找到6,appear赋值为True,结束循环;如果找不到,那么i会增加至len(arr),从而判断不含有6.

下面我们测试一下:

check([1,2,3,4,5,6,7])
# 运行结果: 6 appears in arr? True

check([1,2,3,4])
# 运行结果:UnboundLocalError: local variable 'appear' referenced before assignment

什么鬼,竟然说appear在赋值前使用。这很不科学,因为从上面的代码看,如果找到appear会赋值为True,找不到会赋值为False,怎么会没有赋值呢?

原因是我们想当然的觉得找不到,i会增加至len(arr)。其实并不是这样的,如下面的代码所示:

for i in range(5):
    print(i)
print("after loop i == ", i)
# 运行结果:
	0
	1
	2
	3
	4
	after loop i == 4

这下真相大白了,i并不会想我们设想的那样变成5,而是4.

我们之所以会有错误的设想,其实是受“传统”for循环的影响,以C++代码为例:

int i;
for (i = 0; i < 5; ++i)
	cout << i << endl;
cout << "after loop i == " << i << endl;
// 运行结果
	0
	1
	2
	3
	4
	after loop i == 5

造成这种差异的是二者实现上的差异,range实际上返回了一个迭代器,迭代器依次返回0, 1, 2, 3, 4i不可能变成5;而C++则是通过i < 5来控制语句结束的,当i==5时,for循环结束。

同样是for语句,却因为实现的不同存在这样细微的差异。所以说,一定要注意语言之间的差异,不能想当然的用一种语言写另外一种语言风格的代码,不然很容易出现极其隐蔽的bug。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值