判断是否可以迭代
1. 在python中通过for循环遍历列表、元组、字典等就是迭代(Iteration)
例1:遍历列表
num = [11, 22, 33, 44, 55]
for x in num:
print(x)
打印结果是:
11
22
33
44
55
例2:遍历字符串
for x in 'abcdef':
print(x)
a
b
c
d
e
f
但是有些类型是不能迭代的,或者说不能遍历,例如:int 整形
例3:测试遍历int型
>>> for x in 100:
... print(x)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
TypeError: ‘int’ object is not iterable 就是告诉我们类型不对,‘int’不可迭代
2. 哪些可以迭代?
元组、列表、字典、集合、字符串都可以迭代,也就是说只要是可迭代的对象都可以进行迭代
3. 我们怎么判断一个对象是否可以迭代呢?
可以利用 collection 模块中的 Iterable这个类中的一个子类 isinstance 判断,
例4:判断列表是否可以迭代
>>> from collections import Iterable
>>> isinstance([1, 2, 3],Iterable)
True
>>> isinstance(123,Iterable)
False
isinstance输出True说明能够迭代,输出False说明不能
4. 类/对象 可以迭代吗?
可以!
例5:
from collections.abc import Iterable
class ClassIterable(object):
def __init__(self):
self.contains = list( )
def addList(self, item):
self.contains.append(item)
def __iter__(self):
pass
classIterable = ClassIterable( )
print('ClassIterable是否是可迭代对象', isinstance(classIterable, Iterable))
for temp in ClassIterable:
print(temp)
打印输出:
ClassIterable是否是可迭代对象 True
Traceback (most recent call last):
File ".\1迭代对象.py", line 18, in <module>
for temp in classIterable:
TypeError: iter() returned non-iterator of type 'NoneType'
通过上面程序可以发现,classIterable对象是可以迭代的 ,输出结果是True,但是紧接着就报错了,错误是在18行,也就是用for遍历这个对象的时候,用isinstance判断的结果是可以迭代的,为什么会出现这个情况呢?一个对象如果要迭代,必须要有一个记录迭代过程的
一般情况下对象是不能直接迭代的,如何判断或着说让对象可以迭代呢?在例5的classIterable对象中有一个__iter__方法,这个方法现在什么都没有做,让isinstance判断出ClassIterable可以遍历就是因为它。
判断对象是否可以迭代,就是判断这个对象中是否有__iter__方法
- __iter__方法必须有返回值,并且返回值必须是包含__next__方法的函数,for遍历的时候就是调用__iter__返回值中的__next__方法
- __next__方法返回什么,遍历取到的就是什么
- 例6:
class ClassA(object):
def __init__(self):
self.contains = list( )
def addList(self, item):
self.contains.append(item)
#如果想要一个对象成为可以迭代的对象,即可以使用for,必须使用__iter__方法
def __iter__(self):
return ClassB()
class ClassB(object):
def __next__(self):
return 1
classIterable = ClassA( )
for temp in classIterable:
print(temp)
实现对象迭代就是该对象中有__iter__方法,并且有返回值,这个返回值对象中有__next__方法
例7:迭代取对象列表中的内容
class ClassA(object):
def __init__(self):
self.contains = list( )
def addList(self, item):
self.contains.append(item)
#如果想要一个对象成为可以迭代的对象,即可以使用for,必须使用__iter__方法
def __iter__(self):
return ClassB(self)
class ClassB(object):
def __init__(self, contain):
self.contain = contain
def __next__(self):
return self.contain.contains[0]
classIterable = ClassA( )
classIterable.addList('物品1')
classIterable.addList('物品2')
classIterable.addList('物品3')
for temp in classIterable:
print(temp)
time.sleep(1)
打印结果:
物品1
此时,就会一直取list()中的物品1,会一直循环打印
流程
for开始----->
1.判断ClassA创建的实例对象classIterable是否可以迭代1
2.调用iter函数得到ClassA中__iter__方法的返回值
3.__iter__方法的返回值是一个迭代器。判断是否是迭代器2
4.在__iter__方法中的返回对象中是否有__next__方法
5.__next__方法的返回值取遍历对象中需要遍历的属性
- 判断方法:
:print('ClassIterable是否是可迭代对象:', isinstance(classIterable, Iterable))
↩︎ - 判断方法
:classIterator = iter(classIterable)
:print('classIterator是否是迭代器:', isinstance(classIterator, Iterator))
↩︎