关于类 map
通过文档,可以明确得知, map 是一个类, 不是内置函数
1. 先看简单使用例子: 题目: 1个数字列表, 求一个新列表, 新列表的每个元素,都是旧列表元素的 平方
1 res = map(lambda x: x*x, [1, 2, 3, 4, 5]) 迭代一个列表, 每个元素的平方 2 print(res) <map object at 0x10e1d9470> 3 print(list(res)) [1, 4, 9, 16, 25]
通过第 2行 打印结果得知, res 是 map 实例
第三行, 通过 list() 强制转换, 得到 新列表
2. 注意一个细节, 如果 在第3行代码下, 在 强制 转换一次 res , 会是什么结果呢?
1 res = map(lambda x: x*x, [1, 2, 3, 4, 5]) 2 print(res) 3 print(list(res)) 4 print(list(res))
见证奇迹的结果如下:
<map object at 0x10a0c4470> [1, 4, 9, 16, 25] [] 第4行, 打印结果是个 空 列表
3. 在第2部分代码 先加个 next 取值, 试试
1 res = map(lambda x: x*x, [1, 2, 3, 4, 5]) 2 print(res) 3 print(next(res)) 增加第3行代码, 先使用next, 从res 取值 4 print(list(res)) 5 print(list(res))
看结果:
<map object at 0x101596470> 1 next(res) 打印为 1, 符合预期 [4, 9, 16, 25] 将 res 强制转成列表, 是除了 1 之外的 后续元素 []
4 . 查阅文档, map类, 有 两个方法: __iter__ __next__
也可以通过 print(dir(res)) , 可以看到 有如上上两个方法
这说明, map类 实例对象, res 是一个生成器对象,
每调用一次 next 之后, 就会指向下一个元素.
for 循环遍历 也应是 next 用法, 只能遍历一次, 再次遍历就是 空列表
5. 把第 3部分的代码再改下,看看神奇效果
1 res = map(lambda x: x*x, [1, 2, 3, 4, 5]) 2 print('使用next',next(res)) 3 for item in res: 4 print('for循环', item) 5 print('list转换',list(res))
查看结果:
使用next 1 for循环 4 for循环 9 for循环 16 for循环 25 list转换 []
结论: 对于生成器对象, 取值, 是逐个单向取值, 一旦被取出,就不能再次取值.
建议读者, 根据 代码, 自行体会, 总结, 会更深刻.
扩展:
像类似 map 的还有一些, 比如, filter, zip 等都是同样的,
都是属于生成器对象.
既然是生成器对象, 那就得符合 生成器对象 的规则