Heim  >  Artikel  >  Backend-Entwicklung  >  Der Unterschied zwischen Python-Generatoren und Iteratoren

Der Unterschied zwischen Python-Generatoren und Iteratoren

爱喝马黛茶的安东尼
爱喝马黛茶的安东尼Original
2019-06-24 13:26:313537Durchsuche

Für Containerobjekte wie Listen, Zeichenfolgen, Tupel, Diktate usw. ist es sehr praktisch, zum Durchlaufen eine for-Schleife zu verwenden. Die Funktion iter() wird für das Containerobjekt im Hintergrund der Anweisung aufgerufen. iter() ist eine in Python integrierte Funktion. Die Funktion iter() gibt ein Iteratorobjekt zurück, das die Methode next() definiert, die nacheinander auf die Elemente im Container zugreift. next() ist ebenfalls eine integrierte Funktion von Python. Wenn keine nachfolgenden Elemente vorhanden sind, löst next() eine StopIteration-Ausnahme aus, um die for-Anweisung über das Ende der Schleife zu informieren.

Der Unterschied zwischen Python-Generatoren und Iteratoren

Iterator

Iterator wird verwendet, um uns bei der Aufzeichnung zu helfen die von jeder Iteration besuchte Position. Wenn wir die Funktion next() auf dem Iterator verwenden, gibt der Iterator die Daten an der nächsten Position der aufgezeichneten Position zurück. Tatsächlich wird bei Verwendung der Funktion next() die Methode _next_ des Iteratorobjekts aufgerufen (die Methode _next_ des Objekts in Python3 und die Methode next() des Objekts in Python2). Wenn wir also einen Iterator erstellen möchten, müssen wir dessen _next_-Methode implementieren. Dies reicht jedoch nicht aus. Python erfordert, dass der Iterator selbst auch iterierbar ist. Daher müssen wir auch die _iter_-Methode für den Iterator implementieren, und die _iter_-Methode gibt einen Iterator zurück Das Gerät kann sich selbst zurückgeben.

Erklärung einiger Begriffe:

1. Iteratorprotokoll: Das Objekt muss die next()-Methode bereitstellen, die entweder das nächste Element in der Iteration zurückgibt oder verursacht Eine StopIteration-Ausnahme zum Beenden der Iteration.
2. Iterierbares Objekt: Implementiert das Iterator-Protokollobjekt. Liste, Tupel und Diktat sind alle iterierbar (iterierbare Objekte), aber nicht Iterator (Iteratorobjekte). Sie können diese jedoch mit der integrierten Funktion iter() in Iterable (iterierbare Objekte) umwandeln.
3. Der Kern des for-Elements in der Iterable-Schleife besteht darin, zuerst den Iterator des iterierbaren Objekts Iterable über die Funktion iter() abzurufen und dann kontinuierlich die Methode next() für den erhaltenen Iterator aufzurufen, um den nächsten Wert zu erhalten und weisen Sie es zu. Die Schleife endet, wenn eine StopIteration-Ausnahme auftritt.

Verwandte Empfehlungen: „Python-Video-Tutorial

Pythons eigener Containerobjektfall:

# 随便定义一个list
listArray=[1,2,3]
# 使用iter()函数
iterName=iter(listArray)
print(iterName)
# 结果如下:是一个列表list的迭代器
# <list_iterator object at 0x0000017B0D984278>
 
print(next(iterName))
print(next(iterName))
print(next(iterName))
print(next(iterName))#没有迭代到下一个元素,直接抛出异常
# 1
# 2
# 3
# Traceback (most recent call last):
# File "Test07.py", line 32, in <module>
# StopIteration

Eine der Python-Implementierungen der _iter_-Methode und der Das Klassenobjekt der _next_-Methode ist ein Iterator. Der folgende Fall ist ein Fall der Berechnung der Fibonacci-Folge

class Fib(object):
 def __init__(self, max):
  super(Fib, self).__init__()
  self.max = max
 
 def __iter__(self):
  self.a = 0
  self.b = 1
  return self
 
 def __next__(self):
  fib = self.a
  if fib > self.max:
   raise StopIteration
  self.a, self.b = self.b, self.a + self.b
  return fib
 
# 定义一个main函数,循环遍历每一个菲波那切数
def main():
 # 20以内的数
 fib = Fib(20)
 for i in fib:
  print(i)
 
# 测试
if __name__ == &#39;__main__&#39;:
 main()

Erklärung:

ist in dieser Klasse implementiert und definiert einen _iter_. (self)-Methode, die von iter() aufgerufen wird, wenn die for-Schleife einen Iterator durchläuft und zurückgibt. Denn beim Durchlaufen wird die in Python integrierte Funktion iter() direkt aufgerufen und iter() erhält den Iterator des Objekts durch Aufrufen von _iter_(self). Mit einem Iterator können Sie Elemente einzeln durchlaufen. Beim Durchlaufen nacheinander wird die integrierte Funktion next () auch zum Durchlaufen des Iteratorobjekts verwendet, indem die Methode _next_ (self) des Objekts aufgerufen wird. Wir müssen also die beiden Methoden _iter_(self) und _next_(self) implementieren.

Und da die Methode _next_(self) implementiert ist, geben Sie self bei der Implementierung von _iter_(self) einfach direkt zurück.

Um es in einem Satz zusammenzufassen:

Beim Durchlaufen des benutzerdefinierten Containerobjekts wird die in Python integrierte Funktion iter() verwendet, um _iter_(self) aufzurufen ) des durchlaufenen Objekts, um einen Iterator zu erhalten, und dann verwendet die Schleife next() für diesen Iterator, um _next_(self) des Iteratorobjekts aufzurufen.

Hinweis: _iter_(self) wird nur einmal aufgerufen, während _next_(self) n-mal aufgerufen wird, bis eine StopIteration-Ausnahme auftritt.

Generator

Funktion:

Betrieb verzögern. Das heißt, Ergebnisse werden dann erzielt, wenn sie benötigt werden, und nicht sofort.

Hinweis:

Der Generator kann nur einmal durchlaufen werden.
Generatoren sind eine besondere Art von Iteratoren.

Kategorie:

第一类:生成器函数:还是使用 def 定义函数,但是,使用yield而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次从它离开的地方继续执行。

# 菲波那切数列
def Fib(max):
 n, a, b = 0, 0, 1
 while n < max:
  yield b
  a, b = b, a + b
  n = n + 1
 return &#39;亲!没有数据了...&#39;
# 调用方法,生成出10个数来
f=Fib(10)
# 使用一个循环捕获最后return 返回的值,保存在异常StopIteration的value中
while True:
 try:
  x=next(f)
  print("f:",x)
 except StopIteration as e:
  print("生成器最后的返回值是:",e.value)
  break

第二类:生成器表达式:类似于列表推导,只不过是把一对大括号[]变换为一对小括号()。但是,生成器表达式是按需产生一个生成器结果对象,要想拿到每一个元素,就需要循环遍历。

如下案例加以说明:   

# 一个列表
xiaoke=[2,3,4,5]
# 生成器generator,类似于list,但是是把[]改为()
gen=(a for a in xiaoke)
for i in gen:
 print(i)
#结果是:
2
3
4
5
# 为什么要使用生成器?因为效率。
# 使用生成器表达式取代列表推导式可以同时节省 cpu 和 内存(RAM)。
# 如果你构造一个列表(list)的目的仅仅是传递给别的函数,
# 比如 传递给tuple()或者set(), 那就用生成器表达式替代吧! 
#本案例是直接把列表转化为元组
kk=tuple(a for a in xiaoke)
print(kk)
#结果是:
(2, 3, 4, 5) 
# python内置的一些函数,可以识别这是生成器表达式,外面有一对小括号,就是生成器
result1=sum(a for a in range(3))
print(result1)
# 列表推导式
result2=sum([a for a in range(3)])
print(result2)

区别:

生成器能做到迭代器能做的所有事,而且因为自动创建了 iter()和 next()方法,生成器显得特别简洁,而且生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。除了创建和保存程序状态的自动方法,当发生器终结时,还会自动抛出 StopIteration 异常。

Das obige ist der detaillierte Inhalt vonDer Unterschied zwischen Python-Generatoren und Iteratoren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Was bedeutet def in Python?Nächster Artikel:Was bedeutet def in Python?