天天看點

Python - 疊代器和解析

目錄

  • 可疊代對象
  • 自定義可疊代對象
  • 檔案疊代器
  • 手動疊代:iter()和next()
  • 清單解析
  • 在檔案上使用清單解析
  • 清單解析擴充
  • 集合解析
  • 字典解析

__iter__

方法的類産生的對象為可疊代對象

如何判斷一個對象可疊代?

from collections.abc import Iterable

class MyClass:

    def __iter__(self):
        pass

if __name__ == '__main__':
    my_class = MyClass()
    print(isinstance(my_class, Iterable))  # out: True

           

class MyList:
    def __init__(self):
        self.list = []

    def add_item(self, data):
        self.list.append(data)

    # 傳回疊代器
    def __iter__(self):
        # 建立自定義疊代器
        return MyListIterator(self.list)


class MyListIterator:
    """自定義疊代器類"""
    def __init__(self, my_list):
        self.list = my_list
        self.current_index = 0

    def __next__(self):
        """傳回下一個元素"""
        if self.current_index < len(self.list):
            ret_el = self.list[self.current_index]
            self.current_index += 1
            return ret_el
        else:
            raise StopIteration


if __name__ == '__main__':
    my_list = MyList()
    my_list.add_item('張飛')
    my_list.add_item('關于')
    my_list.add_item('諸葛亮')
    for var in my_list:
        print(var)

           

__next__

方法:

next__方法會疊代一次,到達最後會引發StopIteration異常,

任何這類對象都能以 for循環或其他疊代工具周遊,所有疊代工具内部工作起來都時在每次疊代時調用__next()

并捕捉StopIteration異常來進行離開

1.pen() 函數傳回的是一個可疊代的對象 ,可以與for 循環結合使用

2. readline() 方法會調用__next__() 方法讀取一行資料

3. 到檔案末尾時,next()會引發内置的StopIteration異常, readline()傳回空字元串

>>> f = open('10_session.py', encoding='utf-8')
>>> f.readline()
'import requests\n'
>>> f.readline()
'\n'
>>> f.__next__()
'# 在一次session會話中,可以自動儲存伺服器産生的cookies 資訊,并且自動在下一條請求時附加\n'
>>> f.__next__()
'session = requests.session()\n'
>>>

>>> for line in open('10_session.py', encoding='utf-8'):
...     print(line)
...
import requests

session = requests.session()

url = 'http://httpbin.org/cookies/set/sessioncookie/123456789'

session.get(url)

r = session.get("http://httpbin.org/cookies")

print(r.json())

           

iter(可疊代對象): 傳回一個疊代器

next(疊代器): 會自動調用

__next__

方法,向後疊代一次

next(疊代器) 等價于 疊代器.

__next__

()
>>> L  = [1,2,3,4]
>>> I = iter(L)
>>> type(I)
<class 'list_iterator'>
>>> next(I)
1
>>> next(I)
2
>>> next(I)
3
>>> next(I)
4
>>> next(I)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>>

>>> f = open('10_session.py')
>>> iter(f) == f
True
           

其文法源自于集合理論表示法中的一個結構,該結構對集合中的每個元素應用一個操作。

清單解析寫在一個方括号中,因為它們最終建構的是一個新的清單,以一個自定義表達式開始,

後面接一個for循環,自定義表達式用于處理每一次疊代的元素

清單解析的優點:

比手動的for循環語句快一倍,因為它們的疊代内部是以C語言的速度執行的,對于較大的資料集合,更能發揮出速度的優勢

>>> L = [1,2,3,4]
>>>
>>> data = [x+10 for x in L]
>>> data
[11, 12, 13, 14]
>>>
           

當我們會在序列上的每一項進行操作的時候就可以考慮使用清單解析
>>> f = open('scripts.py')
>>> f.readlines()
['import sys\n', 'print(sys.path)\n', 'x = 2\n', 'print(x ** 33)\n']

# 去除每一行結尾的空白
>>> data = [ line.rstrip() for line in open('scripts.py')]
>>> data
['import sys', 'print(sys.path)', 'x = 2', 'print(x ** 33)']
>>>
           

  1. 表解析中for 循環後面可以跟一個if 表達式,來過濾掉一部分結果、

    2.清單解析也可以變得更複雜,比如嵌套for循環, 多個for子句,

    每個for 子句又可以有一個相關的if子句

# 過濾掉不是p 開頭的行
>>> [ line.rstrip() for line in open('scripts.py') if line[0] == 'p']['print(sys.path)', 'print(x ** 33)']

# 多個for子句的情況
>>> [x+y for x in 'abc' for y in '123']
['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']
           

>>> set(open('scripts.py'))
{'print(x ** 33)\n', 'import sys\n', 'print(sys.path)\n', 'x = 2\n'}
>>> {line for line in open('scripts.py')}
{'print(x ** 33)\n', 'import sys\n', 'print(sys.path)\n', 'x = 2\n'}
           

>>> {key:value for (key,value) in enumerate(open('scripts.py'))}
{0: 'import sys\n', 1: 'print(sys.path)\n', 2: 'x = 2\n', 3: 'print(x ** 33)\n'}
           

本文來自部落格園,作者:abcbca,轉載請注明原文連結:https://www.cnblogs.com/czzz/p/15759675.html