真实情况:

昨晚写到这样的代码

def chartoNum(s):
    dict = {'0': 0, '1': 1, '2': 2, '3': 3, '4': 4}
    return dict[s]


def fn(x, y):
    return x * 10 + y
r = map(chartoNum, "23443")
print(list(r))
r1 = reduce(fn, r)
print(r1)

很不幸的是,报错了 -

TypeError: reduce() of empty sequence with no initial value
@(怒)可是我明明给你reduce值了 --

我将目标锁定在r身上,于是将r替换成map(....)
实测正常。那为什么会这样呢?

首先我们得知道python的迭代器

[button href="https://www.w3schools.com/python/python_iterators.asp"]itertors[/button]

从中你会发现:创建一个迭代器和停止自己看吧,这里只讲一点
列表,元组,字典和集合都是可迭代的对象。它们是可迭代的 容器,您可以从中获得迭代器。
(区别可迭代和迭代器)
所有这些对象都有一个iter(用于获取迭代器的方法,然后经过next去打印。
并且我们一直使用for去遍历一些列表元组字典,实际上就是该for循环创建了一个迭代器对象,并为每个循环执行next()方法。
所以我们才能去遍历得到值
解释器需要迭代对象x时,会自动调用iter(x)

那为什么要介绍迭代器?
我们再来看下reduce的语法

reduce(function, iterable[, initializer])

iterable就是可迭代的对象

对于map在Python 3.x 返回迭代器
所以我们一般需要list,将其返回列表,bug就出现在这里。

!!!!!!
list后迭代器,第一次有值, 第二次就没了
list(r) #有值列表
list(r) #空列表
以至于我们再去调用r的时候为空,但是print r是有值的
这是为什么呢???
list的作用是返回列表,也就是可迭代的对象
list(r) 后再调用next(r)会发现报错StopIteration[collapse title=""]
迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。
[/collapse],这是因为next不到值了,这就说明了list map对象后指针已经到了最后一个,所以再去使用r是空。而print(r)type(r) 这样内置的是重新审查了一遍整体r,因此有值。

而list 字符串等其它可迭代对象,却没有这样的问题,这是因为
这些部分将创建一个新的可迭代对象,然后next对于这些新的

而map本身就是迭代器!!!!
list后返回的是本身,因此next自然是末尾!

于是乎,我们似乎明白了些什么(´இ皿இ`)

python

版权属于:染念
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
更新于: 2021年04月29日 09:06
0
发表评论


180 文章数
673 评论量
4 分类数
184 页面数
已在风雨中度过 7年68天23小时32分
目录
来自 《关于python map迭代的那些事》
© 2024 染念Blog
浙ICP备19020194号-1
暗黑模式
暗黑模式
评论
返回顶部
© 2024 染念Blog
浙ICP备19020194号-1
暗黑模式
暗黑模式
评论
返回顶部