關於python中可迭代物件和迭代器的一些理解

水痕001發表於2018-12-07

很多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、集合資料型別如listdictstr等是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、最簡單也是最粗暴的方式,直接在類中實現兩個魔法函式__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))
    複製程式碼

相關文章