很多
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)) 複製程式碼