# 问题
先来看个例子:
>>> a = ["hxhen", ".", "com"] # 初始化一个字符串列表
>>> b = map(len, a) # 计算列表中每个字符串的长度
>>> list(b) # 转换成列表显示
[5, 1, 3] # 正常显示
>>> list(b) # 同样的操作再做一次
[] # 嗯???数据消失了?
数据消失了吗?其实没有,只不过用这种方式已经获取不到了。
# 原因
map函数的返回值是一个迭代器,list函数等常用操作都会遍历传入的可迭代对象。遍历完迭代器的所有元素之后,索引指针就已经指向了可迭代对象的末尾,此时继续获取它的下一个元素,返回的自然是空值了。
# 解决
解决方式1:一种简单的解决方式是先将结果存成列表,后续可以多次遍历。
>>> a = ["hxhen", ".", "com"] # 初始化一个字符串列表
>>> b = list(map(len, a)) # 计算列表中每个字符串的长度,并将结果转换成列表
>>> list(b) # 转换成列表显示
[5, 1, 3] # 正常显示
>>> list(b) # 转换成列表显示
[5, 1, 3] # 正常显示
>>> # 好吧,我必须得承认将一个list对象转成list对象十分多余……
>>> # 总之用list或者set等其他非迭代器对象保存结果就好了
解决方式2: Python内置的迭代器对象不支持重置 ,可以改用numpy.nditer对象
>>> a = np.nditer([["hxhen", ".", "com"]]) # 把列表转换成numpy的迭代器,注意传入二维列表
>>> [i.item() for i in a] # 遍历一次所有元素
['hxhen', '.', 'com'] # 结果正常显示
>>> [i.item() for i in a] # 再次遍历
[] # 结果为空
>>> a.reset() # 重置迭代器
>>> [i.item() for i in a] # 再次遍历
['hxhen', '.', 'com'] # 结果正常显示
# 下面是可以不看的部分
可以用其他方式再次重现这一现象:
>>> a = ["hxhen", ".", "com"] # 初始化一个字符串列表
>>> c = iter(a) # 将列表转换成可迭代对象
>>> list(c) # 转换成列表显示
['hxhen', '.', 'com'] # 正常显示
>>> list(c) # 再次转换成列表显示
[] # 为空
>>> [c for item in c] # 用列表生成式获取元素
[] # 同样为空
>>> >>> "|".join(c) # 用 join 函数拼接各个元素
'' # 同样为空
>>> next(c) # 此时尝试用 next 函数获取下一个元素
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> # 报错,说明确实到了迭代器末尾
还可以继续往下尝试:
>>> a = ["hxhen", ".", "com"] # 初始化一个字符串列表
>>> c = iter(a) # 将列表转换成可迭代对象
>>> next(c) # 先用 next 函数获取一个元素
'hxhen' # 获取成功
>>> list(c) # 转换成列表显示
['.', 'com'] # 只有两个元素了
>>> next(c) # 再次获取下一个元素
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> # 报错,说明到了迭代器末尾
>>> list(c) # 再次转换成列表显示
[] # 为空