# 元组,列表,字典,字符串,集合,range都是可迭代对象from collections.abc import Iterable
# 3.7以上版本为导入collections.abc# from collections import Iterable# 判断对象是否是指定类型
result =isinstance((3,5), Iterable)print("元组是否是可迭代对象:", result)
result =isinstance([3,5], Iterable)print("列表是否是可迭代对象:", result)
result =isinstance({"name":"张三"}, Iterable)print("字典是否是可迭代对象:", result)
result =isinstance("hello", Iterable)print("字符串是否是可迭代对象:", result)
result =isinstance({3,5}, Iterable)print("集合是否是可迭代对象:", result)
result =isinstance(range(5), Iterable)print("range是否是可迭代对象:", result)
result =isinstance(5, Iterable)print("整数是否是可迭代对象:", result)# 提示: 以后还根据对象判断是否是其它类型,比如以后可以判断函数里面的参数是否是自己想要的类型
result =isinstance(5,int)print("整数是否是int类型对象:", result)classStudent(object):pass
stu = Student()
result =isinstance(stu, Iterable)print("stu是否是可迭代对象:", result)
result =isinstance(stu, Student)print("stu是否是Student类型的对象:", result)
自定义可迭代对象
自定义可迭代对象: 在类里面定义__iter__方法创建的对象就是可迭代对象
from collections.abc import Iterable
# 自定义可迭代对象: 在类里面定义__iter__方法创建的对象就是可迭代对象classMyList(object):def__init__(self):
self.my_list =list()# 添加指定元素defappend_item(self, item):
self.my_list.append(item)def__iter__(self):# 可迭代对象的本质:遍历可迭代对象的时候其实获取的是可迭代对象的迭代器, 然后通过迭代器获取对象中的数据pass
my_list = MyList()
my_list.append_item(1)
my_list.append_item(2)
result =isinstance(my_list, Iterable)print(result)for value in my_list:print(value)
执行结果
Traceback (most recent call last):
True
File "/home/python/Desktop/MyIterable.py", line 24, in <module>
for value in my_list:
TypeError: iter() returned non-iterator of type 'NoneType'
自定义迭代器对象
from collections.abc import Iterable
from collections.abc import Iterator
# 自定义可迭代对象: 在类里面定义__iter__方法创建的对象就是可迭代对象classMyList(object):def__init__(self):
self.my_list =list()# 添加指定元素defappend_item(self, item):
self.my_list.append(item)def__iter__(self):# 可迭代对象的本质:遍历可迭代对象的时候其实获取的是可迭代对象的迭代器, 然后通过迭代器获取对象中的数据
my_iterator = MyIterator(self.my_list)return my_iterator
# 自定义迭代器对象: 在类里面定义__iter__和__next__方法创建的对象就是迭代器对象classMyIterator(object):def__init__(self, my_list):
self.my_list = my_list
# 记录当前获取数据的下标
self.current_index =0# 判断当前对象是否是迭代器
result =isinstance(self, Iterator)print("MyIterator创建的对象是否是迭代器:", result)def__iter__(self):return self
# 获取迭代器中下一个值def__next__(self):if self.current_index <len(self.my_list):
self.current_index +=1return self.my_list[self.current_index -1]else:# 数据取完了,需要抛出一个停止迭代的异常raise StopIteration
my_list = MyList()
my_list.append_item(1)
my_list.append_item(2)
result =isinstance(my_list, Iterable)print(result)for value in my_list:print(value)
遍历的是可迭代对象
for item in Iterable 循环的本质就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束。
遍历的是迭代器
for item in Iterator 循环的迭代器,不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束。
from collections.abc import Iterable
from collections.abc import Iterator
'''
判断是否是可迭代对象:
1.0:能用for循环遍历的对象
2.0:可以使用 isinstance() 判断一个对象是否是 Iterable 对象:
''''''
可迭代对象的本质就是可以向我们提供一个这样的中间“人”即迭代器帮助我们对其进行迭代遍历使用。
可迭代对象通过__iter__方法向我们提供一个迭代器,
我们在迭代一个可迭代对象的时候,
实际上就是先获取该对象提供的一个迭代器,
然后通过这个迭代器来依次获取对象中的每一个数据.
一个类中只要具有__iter__(self)方法,那么该对象就是一个可迭代对象
'''classmyList(object):def__init__(self,n):
self.n = n
def__iter__(self):return MyIterable(self.n)classMyIterable(object):def__init__(self,n):
self.n = n
self.current =0def__iter__(self):return self
def__next__(self):if self.current<self.n:
num = self.current
self.current+=1return num
else:raise StopIteration
# test = MyIterable(20)
test = myList(20)print(isinstance(test,Iterable))print(isinstance(test,Iterator))print(isinstance(MyIterable(10),Iterator))# list、tuple等都是可迭代对象,我们可以通过iter()函数获取这些可迭代对象的迭代器。# 然后我们可以对获取到的迭代器不断使用next()函数来获取下一条数据。# iter()函数实际上就是调用了可迭代对象的__iter__方法# thisIterable = myList()# print(isinstance([],Iterable))# print(isinstance([],Iterator))# print(isinstance(thisIterable,Iterable))# print(isinstance(thisIterable,Iterator))# print(isinstance(MyIterable,Iterable))# print(isinstance(MyIterable,Iterator))# li = [ i for i in range(5)]# print(type(li))# my_list = iter(li)# print(next(my_list))
生成器的创建方法
# 第一种方法:# test = (i for i in range(10))# print(type(test))# 在def函数里面看到有yield关键字那么就是生成器# 第二种方法defmyIterable(n):
current =0while current < n:
num = current
current +=1yield num
test = myIterable(5)for i inrange(5):print(next(test))
deffibonacci(num):
a =0
b =1# 记录生成fibonacci数字的下标
current_index =0print("--11---")while current_index < num:
result = a
a, b = b, a + b
current_index +=1print("--22---")# 代码执行到yield会暂停,然后把结果返回出去,下次启动生成器会在暂停的位置继续往下执行yield result
print("--33---")
fib = fibonacci(5)
value =next(fib)print(value)
value =next(fib)print(value)
value =next(fib)print(value)# for value in fib:# print(value)# 在使用生成器实现的方式中,我们将原本在迭代器__next__方法中实现的基本逻辑放到一个函数中来实现,但是将每次迭代返# 回数值的return换成了yield,此时新定义的函数便不再是函数,而是一个生成器了。简单来说:只要在def中有yield关键字# 的 就称为 生成器
生成器使用return 关键字
deffibonacci(num):
a =0
b =1# 记录生成fibonacci数字的下标
current_index =0print("--11---")while current_index < num:
result = a
a, b = b, a + b
current_index +=1print("--22---")# 代码执行到yield会暂停,然后把结果返回出去,下次启动生成器会在暂停的位置继续往下执行yield result
print("--33---")return"嘻嘻"
fib = fibonacci(5)
value =next(fib)print(value)# 提示: 生成器里面使用return关键字语法上没有问题,但是代码执行到return语句会停止迭代,抛出停止迭代异常# 在python3里面可以使用return关键字,python2不支持# return 和 yield的区别# yield: 每次启动生成器都会返回一个值,多次启动可以返回多个值,也就是yield可以返回多个值# return: 只能返回一次值,代码执行到return语句就停止迭代try:
value =next(fib)print(value)except StopIteration as e:# 获取return的返回值print(e.value)# 生成器里面使用return关键字语法上没有问题,但是代码执行到return语句会停止迭代,抛出停止迭代异常# 在python3里面可以使用return关键字,python2不支持