今天写了个简单的脚本,调了好久才发现这个坑点。。。
python3与迭代对象
关于for的循环
使用zip与不使用zip的区别
今天写了一个脚本,发现结果总是不对,然后发现问题出在如下的位置:
1 2 3 4 5 6 7 8
| class Test(object): def __init__(self, input_num): self.weight = [0.0 for _ in range(input_num)] def test(self, input_num): weight_num = 0 for i,j in input_num, self.weight: print("i is {} and j is {}".format(i,j))
|
(有一点改动)
然后发现一个奇怪的事情,当我调用test
的函数的时候,输出如下:
1 2 3
| >>> test.test([1,2]) i is 1 and j is 2 i is 0.0 and j is 0.0
|
嗯嗯???

我就是懒了一下没写zip
,怎么就遍历错了呢??
我原先的目的
这个原先的想法是让i遍历input_num,j遍历weight,正常的写法大概就是如下:
1
| for i, j in zip(input_num, weight)
|
进一步理解
后来再大佬的点拨下,发现这个表达式完全可以如此理解:
1
| for (i,j) in (tuple_of_input_num, tuple_of_weight)
|
这个写法可能不妥,大概表达的意思是i,j作为一个整体,然后依次 unpack in关键字后面的数据。
然后我们再修改一下代码:
1 2 3
| >>> input_num.append(5) >>> for i,j in input_num, weight: print("i is {} and j is {}".format(i,j))
|
然后发出了如下的报错:
1
| ValueError: too many values to unpack (expected 2)
|
果然,这里是把i,j
作为了一个整体来考虑数据。
ZIP的原理
那zip
是怎么实现同时迭代多个对象的呢?我们来看一下接下来的代码:
1 2 3 4 5 6
| >>> t = zip([1,2],[3,4]) >>> i,j = t >>> i (1, 3) >>> j (2, 4)
|
可以看到,zip
会将当前的两个可迭代对象放在两个tuple
里面,也就是说,其实我们如下的代码:
1
| for i,j in zip([1,2], [3,4])
|
等价于
总结
- 记得另一位大佬好像讲过,python里面万物皆tuple,这里完全都体会到了
- 写代码的时候记得写测试。。。
关于迭代的方式
过几天又遇到了一个奇怪的现象:
1 2 3 4
| >>> tmp = [(i,j) for i in [1,2,3] for j in [4,5,6] ]
|
我理想中的输出是:
但是实际上却是:
1
| [(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]
|
仔细思考之后,大概明白了上述的写法其实应该等价于
1 2 3
| for i in [1,2,3]: for j in [4,5,6]: tmp.append((i,j))
|
emmm……感觉我对python还是了解不够啊