欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python中迭代器與生成器的用法

 更新時間:2022年05月28日 10:53:46   作者:springsnow  
這篇文章介紹了Python中迭代器與生成器的用法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

一、迭代器(foreach)

1、可迭代的對象

內置有__iter__方法的都叫可迭代的對象。

Python內置str、list、tuple、dict、set、file都是可迭代對象。

x = 1.__iter__  # SyntaxError: invalid syntax

# 以下都是可迭代的對象
name = 'nick'.__iter__
print(type(name))  # 'method-wrapper'>

2、迭代器對象

執(zhí)行可迭代對象的__iter__方法,拿到的返回值就是迭代器對象。

只有字符串和列表都是依賴索引取值的,而其他的可迭代對象都是無法依賴索引取值的,只能使用迭代器對象。

  • 內置有__iter__方法,執(zhí)行該方法會拿到迭代器本身。
  • 內置__next__方法,執(zhí)行該方法會拿到迭代器對象中的一個值。
s = 'hello'
iter_s = s.__iter__()
print(type(iter_s))  # 'str_iterator'> iter_s為迭代器對象

while True:
    try:
        print(iter_s.__next__())
    except StopIteration:
        break
#hello

3、迭代器有兩個基本的方法:iter() 和 next()。

s = 'hello'
iter_s = iter(s) # 創(chuàng)建迭代器對象
print(type(iter_s))  #  iter_s為迭代器對象

while True:
    try:
        print(next(iter_s)) # 輸出迭代器的下一個元素

    except StopIteration:
        break
# hello

4、for迭代器循環(huán)

可迭代對象可以直接使用常規(guī)for語句進行遍歷

for循環(huán)稱為迭代器循環(huán),in后必須是可迭代的對象。

#str
name = 'nick' 
for x in name:
    print(x)

#list
for x in [None, 3, 4.5, "foo", lambda: "moo", object, object()]:
    print("{0}  ({1})".format(x, type(x)))

#dict
d = {
    '1': 'tasty',
    '2': 'the best',
    '3 sprouts': 'evil',
    '4': 'pretty good'
}

for sKey in d:
    print("{0} are {1}".format(sKey, d[sKey]))

#file
f = open('32.txt', 'r', encoding='utf-8')
for x in f:
    print(x)
f.close()

5、實現(xiàn)迭代器(__next__和__iter__)

把一個類作為一個迭代器使用需要在類中實現(xiàn)兩個方法 __iter__() 與 __next__() 。

  • __iter__() 方法返回一個特殊的迭代器對象, 這個迭代器對象實現(xiàn)了 __next__() 方法并通過 StopIteration 異常標識迭代的完成。
  • __next__() 方法會返回下一個迭代器對象。
  • StopIteration 異常用于標識迭代的完成,防止出現(xiàn)無限循環(huán)的情況,在 __next__() 方法中我們可以設置在完成指定循環(huán)次數(shù)后觸發(fā) StopIteration 異常來結束迭代。

創(chuàng)建一個返回數(shù)字的迭代器,初始值為 1,逐步遞增 1,在 20 次迭代后停止執(zhí)行:

class MyNumbers:
  def __iter__(self):
    self.a = 1
    return self
 
  def __next__(self):
    if self.a <= 20:
      x = self.a
      self.a += 1
      return x
    else:
      raise StopIteration
 
myclass = MyNumbers()
myiter = iter(myclass)
 
for x in myiter:
  print(x)

1、模擬range

class Range:
    def __init__(self, n, stop, step):
        self.n = n
        self.stop = stop
        self.step = step

    def __next__(self):
        if self.n >= self.stop:
            raise StopIteration
        x = self.n
        self.n += self.step
        return x

    def __iter__(self):
        return self


for i in Range(1, 7, 3):
    print(i)

#1
#4

2、斐波那契數(shù)列

class Fib:
    def __init__(self):
        self._a = 0
        self._b = 1

    def __iter__(self):
        return self

    def __next__(self):
        self._a, self._b = self._b, self._a + self._b
        return self._a


f1 = Fib()
for i in f1:
    if i > 100:
        break
    print('%s ' % i, end='')

# 1 1 2 3 5 8 13 21 34 55 89

二、生成器

1、yield

在 Python 中,使用了 yield 的函數(shù)被稱為生成器(generator)。

跟普通函數(shù)不同的是,生成器是一個返回迭代器的函數(shù),只能用于迭代操作,更簡單點理解生成器就是一個迭代器。

在調用生成器運行的過程中,每次遇到 yield 時函數(shù)會暫停并保存當前所有的運行信息,返回 yield 的值, 并在下一次執(zhí)行 next() 方法時從當前位置繼續(xù)運行。

調用一個生成器函數(shù),返回的是一個迭代器對象。

yield后面可以加多個數(shù)值(可以是任意類型),但返回的值是元組類型的。

  • 提供一種自定義迭代器的方式
  • yield可以暫停住函數(shù),并提供當前的返回值
import sys


def fibonacci(n):  # 函數(shù) - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if counter > n:
            return
        yield a
        a, b = b, a + b
        counter += 1


f = fibonacci(10)  #f 是一個生成器
print(type(f))  # 'generator'>

while True:
    try:
        print(next(f), end=" ")
    except StopIteration:
        sys.exit()

yield和return:

  • 相同點:兩者都是在函數(shù)內部使用,都可以返回值,并且返回值沒有類型和個數(shù)的限制
  • 不同點:return只能返回一次值;yield可以返回多次值

2、自定義range()方法

def my_range(start, stop, step=1):
    while start < stop:
        yield start
        start += 1


g = my_range(0, 3)
print(f"list(g): {list(g)}")

復雜版本:

def range(*args, **kwargs):
    if not kwargs:
        if len(args) == 1:
            count = 0
            while count < args[0]:
                yield count
                count += 1
        if len(args) == 2:
            start, stop = args
            while start < stop:
                yield start
                start += 1
        if len(args) == 3:
            start, stop, step = args
            while start < stop:
                yield start
                start += step

    else:
        step = 1

        if len(args) == 1:
            start = args[0]
        if len(args) == 2:
            start, stop = args

        for k, v in kwargs.items():
            if k not in ['start', 'step', 'stop']:
                raise ('參數(shù)名錯誤')

            if k == 'start':
                start = v
            elif k == 'stop':
                stop = v
            elif k == 'step':
                step = v

        while start < stop:
            yield start
            start += step


for i in range(3):
    print(i)  # 0,1,2

for i in range(99, 101):
    print(i)  # 99,100

for i in range(1, 10, 3):
    print(i)  # 1,4,7

for i in range(1, step=2, stop=5):
    print(i)  # 1,3

for i in range(1, 10, step=2):
    print(i)  # 1,3,5,7,9

3、生成器表達式(i.for .in)

把列表推導式的[]換成()就是生成器表達式 。

優(yōu)點:比起列表推導式,可以省內存,一次只產(chǎn)生一個值在內存中

t = (i for i in range(10))
print(t)  # <generator object  at 0x00000000026907B0>
print(next(t))  # 0
print(next(t))  # 1

舉例:

with open('32.txt', 'r', encoding='utf8') as f:
    nums = [len(line) for line in f]  # 列表推導式相當于直接給你一筐蛋

print(max(nums))  # 2


with open('32.txt', 'r', encoding='utf8') as f:
    nums = (len(line) for line in f)  # 生成器表達式相當于給你一只老母雞。

print(max(nums))  # ValueError: I/O operation on closed file.

到此這篇關于Python迭代器與生成器的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • Pycharm遠程調試和MySQL數(shù)據(jù)庫授權問題

    Pycharm遠程調試和MySQL數(shù)據(jù)庫授權問題

    這篇文章主要介紹了Pycharm遠程調試和MySQL數(shù)據(jù)庫授權問題,文章內容介紹詳細,需要的小伙伴可以參考一下,希望對你的學習或工作有所幫助
    2022-03-03
  • jupyter?notebook加載和運行.py文件方式

    jupyter?notebook加載和運行.py文件方式

    這篇文章主要介紹了jupyter?notebook加載和運行.py文件方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • python程序調用遠程服務的步驟詳解

    python程序調用遠程服務的步驟詳解

    這篇文章主要介紹了python程序調用遠程服務的步驟詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-03-03
  • Flask深入了解Jinja2引擎的用法

    Flask深入了解Jinja2引擎的用法

    Jinja2是基于python的模板引擎,功能比較類似于于PHP的smarty,J2ee的Freemarker和velocity。 它能完全支持unicode,并具有集成的沙箱執(zhí)行環(huán)境,應用廣泛。jinja2使用BSD授權
    2022-07-07
  • Python 通過調用接口獲取公交信息的實例

    Python 通過調用接口獲取公交信息的實例

    今天小編就為大家分享一篇Python 通過調用接口獲取公交信息的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • python dict亂碼如何解決

    python dict亂碼如何解決

    在本篇文章里小編給大家分享了關于python dict亂碼解決方法,需要的朋友們可以參考下。
    2020-06-06
  • Python靜態(tài)Web服務器面向對象處理客戶端請求

    Python靜態(tài)Web服務器面向對象處理客戶端請求

    這篇文章主要為大家介紹了Python面向對象實現(xiàn)靜態(tài)Web服務器處理客戶端請求示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • pygame學習筆記(3):運動速率、時間、事件、文字

    pygame學習筆記(3):運動速率、時間、事件、文字

    這篇文章主要介紹了pygame學習筆記(3):運動速率、時間、事件、文字,本文講解了運動速率、事件、字體及字符顯示等內容,需要的朋友可以參考下
    2015-04-04
  • Python?tkinter?多選按鈕控件?Checkbutton方法

    Python?tkinter?多選按鈕控件?Checkbutton方法

    這篇文章主要介紹了Python?tkinter?多選按鈕控件?Checkbutton方法,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-07-07
  • 一次搞懂hasattr()/getattr()/setattr()在Python中的應用

    一次搞懂hasattr()/getattr()/setattr()在Python中的應用

    在Python中,hasattr()、getattr()和setattr()是一組內置函數(shù),本文將從入門到精通,全面介紹hasattr()、getattr()和setattr()函數(shù)的用法和相關知識點,需要的可以了解下
    2023-08-08

最新評論