很多
python
教程中,对python
的解释不容易理解,本文记录自己的理解和体会,是对迭代器和生成器的初步理解
一、关于迭代的认识
给定一个列表、元祖、字典、甚至字符串,我们使用
for
去遍历,这样我们叫迭代
- 1、列表的迭代
list1 = ['哈哈', '西西', '嘻嘻']
for x in list1:
print(x)
- 2、列表中需要迭代出下标使用
enumerate
list1 = ['哈哈', '西西', '嘻嘻']
for index, value in enumerate(list1):
print(index, value)
- 3、元祖和字符串的迭代与列表的类似,一样的可以使用
enumerate
进行下标迭代 - 4、字典的迭代方式一
dict1 = {'name': '张三', 'age': 20, 'gender': '男'}
for item in dict1:
print(item)
- 5、字典的迭代方式二
dict1 = {'name': '张三', 'age': 20, 'gender': '男'}
for key in dict1.keys():
print(key)
- 6、字典的迭代方式三
dict1 = {'name': '张三', 'age': 20, 'gender': '男'}
for value in dict1.values():
print(value)
- 7、字典的迭代方式四
dict1 = {'name': '张三', 'age': 20, 'gender': '男'}
for k, v in dict1.items():
print(k, v)
二、可迭代与迭代器的区别
- 1、可迭代一般都可以使用
for
来遍历 - 2、迭代器不仅仅可以使用
for
遍历还可以使用next()
函数一次获取一个元素 - 3、可迭代转换迭代对象使用
iter(可迭代对象)
- 4、判断可迭代对象与迭代器的方式
from collections.abc import Iterator, Iterable
# Iterable 表示可迭代对象
# Iterator 表示迭代器
list1 = [1, 2, 3]
print(isinstance(list1, Iterator))
print(isinstance(list1, Iterable))
print(isinstance(iter(list1), Iterator))
- 5、集合数据类型如
list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象
三、自己实现一个可迭代的对象
- 1、方式一(在类中实现
__getitem__
魔法函数)
from collections.abc import Iterator, Iterable
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
def __getitem__(self, item):
return self.employee[item]
if __name__ == "__main__":
company = Company(['张三', '李四', '王五'])
print(isinstance(company, Iterable))
print(isinstance(company, Iterator))
print(isinstance(iter(company), Iterator))
for item in company:
print(item)
- 2、方式二(在类中实现
__iter__
魔法函数,需要结合__next__
魔法函数)其实已经是迭代器
from collections.abc import Iterator, Iterable
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
self.index = 0
def __iter__(self):
return self
def __next__(self):
try:
current_val = self.employee[self.index]
except IndexError:
raise StopIteration
self.index += 1
return current_val
if __name__ == "__main__":
company = Company(['张三', '李四', '王五'])
print(isinstance(company, Iterable))
print(isinstance(company, Iterator))
for item in company:
print(item)
- 3、总结
- 1.
iter
内置函数会调用__iter__
魔法函数,如果没有__iter__
魔法函数就会去调用__getitem__
魔法函数 - 通过
isinstance(company, Iterable)
判断对象是否可迭代 - 通过
isinstance(company, Iterator)
判断对象是否为迭代器 - 可迭代器对象不代表是迭代器,但是可以通过
iter()
函数将可迭代的转换为迭代器
- 1.
四、自定义迭代器
- 1、最简单也是最粗暴的方式,直接在类中实现两个魔法函数
__iter__
和__next__
函数
from collections import Iterable, Iterator
class Foo(object):
def __init__(self, start, stop):
self.start = start
self.stop = stop
def __iter__(self):
return self
def __next__(self):
if self.start > self.stop:
raise StopIteration
self.start += 1
return self.start
if __name__ == "__main__":
foo = Foo(1, 5)
print(isinstance(foo, Iterable))
print(isinstance(foo, Iterator))
- 2、单独定义一个类来继承迭代器,必须实现
__next__
魔法函数
from collections.abc import Iterable, Iterator
class MyInterator(Iterator):
"""
定义一个迭代器
"""
def __init__(self, employee_list):
self.iter_list = employee_list
self.index = 0
def __next__(self):
try:
word = self.iter_list[self.index]
except IndexError:
raise StopIteration
self.index += 1
return word
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
self.index = 0
def __iter__(self):
return MyInterator(self.employee)
if __name__ == "__main__":
company = Company(['张三', '李四', '王五'])
print(isinstance(company, Iterator))
print(isinstance(company, Iterable))