Python的迭代器和生成器

Jun 10, 2016 pm 03:08 PM
python ビルダー イテレーター

先说迭代器,对于string、list、dict、tuple等这类容器对象,使用for循环遍历是很方便的。在后台for语句对容器对象调用iter()函数,iter()是python的内置函数。iter()会返回一个定义了next()方法的迭代器对象,它在容器中逐个访问容器内元素,next()也是python的内置函数。在没有后续元素时,next()会抛出一个StopIteration异常,通知for语句循环结束。比如:

>>> s = 'abc'
>>> it = iter(s)
>>> it
<str_iterator object at 0x7f71fefe9d68>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
StopIteration
ログイン後にコピー

上面说的都是python自带的容器对象,它们都实现了相应的迭代器方法,那如果是自定义类需要遍历怎么办?方法很简单,对这个类AClass,实现一个__iter__(self)方法,使其返回一个带有__next__(self)方法的对象就可以了。如果你在AClass刚好也定义了__next__(self)方法(一般使用迭代器都会定义),那在__iter__里只要返回self就可以。废话少说,先上代码:

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

def main():
  fib = Fib(100)
  for i in fib:
    print(i)

if __name__ == '__main__':
  main()

ログイン後にコピー

简单讲下代码会干什么,定义了一个Fib类,用于生成fibonacci序列。用for遍历时会逐个打印生成的fibonacci数,max是生成的fibonacci序列中数字大小的上限。

在类的实现中,定义了一个__iter__(self)方法,这个方法是在遍历时被iter()调用,返回一个迭代器。因为在遍历的时候,是直接调用的python内置函数iter(),由iter()通过调用__iter__(self)获得对象的迭代器。有了迭代器,就可以逐个遍历元素了。而逐个遍历的时候,也是使用内置的next()函数通过调用对象的__next__(self)方法对迭代器对象进行遍历。所以要实现__iter__(self)和__next__(self)。而且因为实现了__next__(self),所以在实现__iter__(self)的时候,直接返回self就可以。

为了更好理解,我再简单重复下上面说的那一段:在循环遍历自定义容器对象时,会使用python内置函数iter()调用遍历对象的__iter__(self)获得一个迭代器,之后再循环对这个迭代器使用next()调用迭代器对象的__next__(self)。__iter__只会被调用一次,而__next__会被调用 n 次。

下面说生成器。

生成器(Generator)是创建迭代器的简单而强大的工具。它们写起来就像是正规的函数,只是在需要返回数据的时候使用yield语句。每次next()被调用时,生成器会返回它脱离的位置(它记忆语句最后一次执行的位置和所有的数据值)。以下示例演示了生成器可以很简单的创建出来:

>>> def reverse(data):
...   for index in range(len(data)-1, -1, -1):
...     yield data[index]
... 
>>> for char in reverse('hello'):
...   print(char)
... 
o
l
l
e
h
ログイン後にコピー

关于迭代器和生成器的区别,生成器能做到迭代器能做的所有事,而且因为自动创建了__iter__()和 next()方法,生成器显得特别简洁,而且生成器也是高效的。除了创建和保存程序状态的自动方法,当发生器终结时,还会自动抛出StopIteration异常。一个带有yield的函数就是一个 生成器,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用next()(在 for 循环中会自动调用next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个yield语句就会中断,并返回一个迭代值,下次执行时从yield的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被yield中断了数次,每次中断都会通过yield返回当前的迭代值(yield暂停一个函数,next()从其暂停处恢复其运行)。

另外对于生成器,python还提供了一个生成器表达式:类似与一个yield值的匿名函数。表达式本身看起来像列表推到, 但不是用方括号而是用圆括号包围起来:

>>> unique_characters = {'E', 'D', 'M', 'O', 'N', 'S', 'R', 'Y'}
>>> gen = (ord(c) for c in unique_characters)
>>> gen
<generator object <genexpr> at 0x7f2be4668678>
>>> for i in gen:
...   print(i)
... 
69
79
83
77
82
78
89
68
>>> 
ログイン後にコピー

如果需要,可以将生成器表达式传给tuple、list或是set来迭代所有的值并且返回元组、列表或是集合。在这种情况下,不需要一对额外的括号 ———— 直接将生成器表达式 ord(c) for c in unique_characters传给tuple()等函数就可以了, Python 会推断出它是一个生成器表达式。

最后,为什么要使用生成器?因为效率。使用生成器表达式取代列表解析可以同时节省 cpu 和 内存(ram)。如果你构造一个列表的目的仅仅是传递给别的函数,(比如 传递给tuple()或者set()), 那就用生成器表达式替代吧!

以上所述就是本文的全部内容了,希望大家能够喜欢。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

mysqlは支払う必要がありますか mysqlは支払う必要がありますか Apr 08, 2025 pm 05:36 PM

MySQLには、無料のコミュニティバージョンと有料エンタープライズバージョンがあります。コミュニティバージョンは無料で使用および変更できますが、サポートは制限されており、安定性要件が低く、技術的な能力が強いアプリケーションに適しています。 Enterprise Editionは、安定した信頼性の高い高性能データベースを必要とするアプリケーションに対する包括的な商業サポートを提供し、サポートの支払いを喜んでいます。バージョンを選択する際に考慮される要因には、アプリケーションの重要性、予算編成、技術スキルが含まれます。完璧なオプションはなく、最も適切なオプションのみであり、特定の状況に応じて慎重に選択する必要があります。

hadidb:pythonの軽量で水平方向にスケーラブルなデータベース hadidb:pythonの軽量で水平方向にスケーラブルなデータベース Apr 08, 2025 pm 06:12 PM

hadidb:軽量で高レベルのスケーラブルなPythonデータベースHadIDB(HadIDB)は、Pythonで記述された軽量データベースで、スケーラビリティが高くなっています。 PIPインストールを使用してHADIDBをインストールする:PIPINSTALLHADIDBユーザー管理CREATEユーザー:CREATEUSER()メソッド新しいユーザーを作成します。 Authentication()メソッドは、ユーザーのIDを認証します。 fromhadidb.operationimportuseruser_obj = user( "admin"、 "admin")user_obj。

MySQLワークベンチはMariadBに接続できますか MySQLワークベンチはMariadBに接続できますか Apr 08, 2025 pm 02:33 PM

MySQLワークベンチは、構成が正しい場合、MariadBに接続できます。最初にコネクタタイプとして「mariadb」を選択します。接続構成では、ホスト、ポート、ユーザー、パスワード、およびデータベースを正しく設定します。接続をテストするときは、ユーザー名とパスワードが正しいかどうか、ポート番号が正しいかどうか、ファイアウォールが接続を許可するかどうか、データベースが存在するかどうか、MariadBサービスが開始されていることを確認してください。高度な使用法では、接続プーリングテクノロジーを使用してパフォーマンスを最適化します。一般的なエラーには、不十分な権限、ネットワーク接続の問題などが含まれます。エラーをデバッグするときは、エラー情報を慎重に分析し、デバッグツールを使用します。ネットワーク構成を最適化すると、パフォーマンスが向上する可能性があります

MongoDBデータベースパスワードを表示するNAVICATの方法 MongoDBデータベースパスワードを表示するNAVICATの方法 Apr 08, 2025 pm 09:39 PM

Hash値として保存されているため、Navicatを介してMongoDBパスワードを直接表示することは不可能です。紛失したパスワードを取得する方法:1。パスワードのリセット。 2。構成ファイルを確認します(ハッシュ値が含まれる場合があります)。 3.コードを確認します(パスワードをハードコードできます)。

MySQLを解く方法は、ローカルホストに接続できません MySQLを解く方法は、ローカルホストに接続できません Apr 08, 2025 pm 02:24 PM

MySQL接続は、次の理由が原因である可能性があります。MySQLサービスは開始されず、ファイアウォールは接続をインターセプトし、ポート番号が間違っています。ユーザー名またはパスワードが間違っています。My.cnfのリスニングアドレスは不適切に構成されています。トラブルシューティング手順には以下が含まれます。 2.ファイアウォール設定を調整して、MySQLがポート3306をリッスンできるようにします。 3.ポート番号が実際のポート番号と一致していることを確認します。 4.ユーザー名とパスワードが正しいかどうかを確認します。 5. my.cnfのバインドアドレス設定が正しいことを確認してください。

mysqlはインターネットが必要ですか? mysqlはインターネットが必要ですか? Apr 08, 2025 pm 02:18 PM

MySQLは、基本的なデータストレージと管理のためにネットワーク接続なしで実行できます。ただし、他のシステムとのやり取り、リモートアクセス、または複製やクラスタリングなどの高度な機能を使用するには、ネットワーク接続が必要です。さらに、セキュリティ対策(ファイアウォールなど)、パフォーマンスの最適化(適切なネットワーク接続を選択)、およびデータバックアップは、インターネットに接続するために重要です。

高負荷アプリケーションのMySQLパフォーマンスを最適化する方法は? 高負荷アプリケーションのMySQLパフォーマンスを最適化する方法は? Apr 08, 2025 pm 06:03 PM

MySQLデータベースパフォーマンス最適化ガイドリソース集約型アプリケーションでは、MySQLデータベースが重要な役割を果たし、大規模なトランザクションの管理を担当しています。ただし、アプリケーションのスケールが拡大すると、データベースパフォーマンスのボトルネックが制約になることがよくあります。この記事では、一連の効果的なMySQLパフォーマンス最適化戦略を検討して、アプリケーションが高負荷の下で効率的で応答性の高いままであることを保証します。実際のケースを組み合わせて、インデックス作成、クエリ最適化、データベース設計、キャッシュなどの詳細な主要なテクノロジーを説明します。 1.データベースアーキテクチャの設計と最適化されたデータベースアーキテクチャは、MySQLパフォーマンスの最適化の基礎です。いくつかのコア原則は次のとおりです。適切なデータ型を選択し、ニーズを満たす最小のデータ型を選択すると、ストレージスペースを節約するだけでなく、データ処理速度を向上させることもできます。

Amazon AthenaでAWS接着クローラーの使用方法 Amazon AthenaでAWS接着クローラーの使用方法 Apr 09, 2025 pm 03:09 PM

データの専門家として、さまざまなソースから大量のデータを処理する必要があります。これは、データ管理と分析に課題をもたらす可能性があります。幸いなことに、AWS GlueとAmazon Athenaの2つのAWSサービスが役立ちます。

See all articles