📕
innohub
  • KEEP LEARNING
  • WebInfo
    • JS 部分运算符操作
    • javascript 中的object array
    • 错误处理以及异常捕获
    • JavaScript Bases
    • LaoZi & Confucius
  • PyInfo
    • Python3 输入与输出
    • Python3OS
    • python 修饰器的使用
    • python3 与mysql数据库连接使用实例
    • Format-specifier
    • CGI初学踩坑
    • Django 项目测试
    • Assert-info
    • 使用ngnix和uWSGI配置Django
    • write|SVN​
    • Matplotlib 基本使用
    • 重读 Python 官方文档
    • Python3 Base
    • python3 多线程
    • Python3 函数解析
    • python3 str 对象的基本操作
    • protocl buffers
    • Iterator-Generator
    • Django base
    • Decorator 2
    • Export to wheel or egg-info
    • 三. 运算、数据及逻辑
  • GoInfo
    • Info
      • Select 语句使用
      • First class function
      • Work Pools
      • StructTag
      • Go struct
      • 常用函数
      • Strings操作
      • Golang Bases
      • 数组以及切片
      • 文件操作
      • Golang 中的指针类型
      • Golang Map 类型
      • Reflection
      • 函数闭包
      • 接口
      • Panic and Recover
      • Go中的错误处理
      • 并发
      • defer usage
      • Method in golang
      • Object-oriented Programming
      • Goalng 包管理机制
  • RustInfo
    • Info
      • 包、crate、模块
      • Rust 中的错误处理
      • 智能指针
      • 泛型 generics
      • 数据布局与内存对齐
      • Functions and methods
      • 无畏并发
      • Actix-web 基本使用
      • Got from guessing game
      • 结构体的使用
      • Rust 中的函数式语言功能
      • 集合类型
      • 枚举以及模式匹配
      • Slice 类型
      • 生命周期
      • 测试
      • Rust 中的所有权
      • trait
      • 不安全 Rust
      • Format_print
      • Rust 通用编程概念
      • Macro
  • OS
    • info
      • 内存屏障 -- Part 1
      • 内存屏障 -- Part 2
      • CPU 上下文切换
      • 文件读写与零拷贝
      • ELF 文件
  • MySql
    • info
      • MySql 架构与历史
      • 02-key
  • kubernetes
    • 第二章 k8s 基本概念
    • 第一章 Kubernetes -- 伟大舵手
  • Redis
    • info
      • Redis 总览
      • 02-underline-ds
  • Shell&CInfo
    • GCC 与make的使用
    • C++ 中 malloc 与 new
    • 位运算符操作
    • Base of C macro
    • C 语言中 extern 关键字的用法
  • Distributed
    • info
      • 分布式理论概述
  • Java
    • info
      • Java 内存模型
  • Prometheus
    • Prometheus -- 不灭之火
Powered by GitBook
On this page
  • Python3 迭代器与生成器
  • 一、关系架构
  • 二、详细描述
  • 1.容器 container
  • 2.可迭代对象
  • 3.迭代器
  • 4.生成器
  • 5.生成器表达式

Was this helpful?

  1. PyInfo

Iterator-Generator

Previousprotocl buffersNextDjango base

Last updated 5 years ago

Was this helpful?

Python3 迭代器与生成器

一、关系架构

Python数据结构中常用的概念:
容器(container)、可迭代对象(iterable)、迭代器(itertor)、生成器(generator)的关系及概念如下
image

二、详细描述

1.容器 container

由关系图可知,容器由集合、元组、字典等产生,是一种可以把多个元素组织在一起的数据结构 通常把这些元素存储在内存中(但也有特例,比如迭代器和生成器对象) 常见的容器对象:

  • list, deque, ….

  • set, frozensets, ….

  • dict, defaultdict, OrderedDict, Counter, ….

  • tuple, namedtuple, …

  • str

可以询问某元素是否在容器中:

# 某元素是否在字典的键值中
>>> d = {'a':652, 'ds':565}
>>> assert 'a' in d
>>> assert 65226 not in d

2.可迭代对象

很多容器是可迭代对象,所有可以返回一个迭代器的对象都是一个可迭代对象

比如一个打开的file ,socket

例如:

>>> x = [1, 2, 3]
>>> y = iter(x)
>>> z = iter(x)
>>> next(y)
1
>>> next(y)
2
>>> next(z)
1
>>> type(x)
<class 'list'>
>>> type(y)
<class 'list_iterator'>

​ 这里x是一个可迭代对象,可迭代对象和容器一样是一种通俗的叫法,并不是指某种具体的数据类型,list是可迭代对象,dict是可迭代对象,set也是可迭代对象。y和z是两个独立的迭代器,迭代器内部持有一个状态,该状态用于记录当前迭代所在的位置,以方便下次迭代的时候获取正确的元素。迭代器有一种具体的迭代器类型,比如list_iterator,set_iterator。可迭代对象实现了__iter__方法,该方法返回一个迭代器对象。

# 当运行代码
x =  [1, 2, 3]
for ele in x:
    pass

实际执行情况:

3.迭代器

迭代器(itertor)是可以记住遍历位置的对象,是访问集合元素的一种方式,从第一个元素开始直到遍历结束 任何实现了__iter__ __next__ 方法的都是迭代器前者返回迭代器自身,后者返回下一个值,若无其他元素则抛出StopIteration异常

基本方法:

:black_flag: iter():传入一个序列对象,建立其对应的迭代器对象

:black_flag: next():访问下一个元素

实例:

list = [1, 2, 3, 4]
it = iter(list)
print(next(it))
>>> 1
print(next(it))
>>>2

list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象
for x in it:
    print (x, end=" ")
输出:
1 2 3 4

import sys         # 引入 sys 模块

list=[1,2,3,4]
it = iter(list)    # 创建迭代器对象

while True:
    try:
        print (next(it))
    except StopIteration:
        sys.exit()

生成无限序列:

>>> from itertools import cycle
>>> col = cycle(['red', 'yellow', 'blue'])
>>> col
<itertools.cycle object at 0x7f060aeeb438>
>>> next(col)
'red'
>>> next(col)
'yellow'
>>> next(col)
'blue'
>>> next(col)
'red'
>>> next(col)
'yellow'
>>> next(col)
'blue'

由无限序列截取有限序列:

>>> from itertools import islice
>>> co = cycle(['red', 'yellow', 'blue'])
>>> lim = islice(co, 0, 5)
>>> for x in lim:
...     print(x, end=' ')
... 
red yellow blue red yellow

以斐波那契数列定义迭代器:

class Fib:
    def __init__(self):
        self.prev = 0
        self.curr = 1

    def __iter__(self):
        return self

    def __next__(self):
        value = self.curr
        self.curr += self.prev
        self.prev = value
        return value

>>> f = Fib()
>>> list(islice(f, 0, 10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

Fib既是一个可迭代对象(因为它实现了__iter__方法),又是一个迭代器(因为实现了__next__方法)。实例变量prev和curr用户维护迭代器内部的状态。每次调用next()方法的时候做两件事:

  1. 为下一次调用next()方法修改状态

  2. 为当前这次调用生成返回结果

迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。

4.生成器

​ 生成器算得上是Python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。它不需要再像上面的类一样写__iter__()和__next__()方法了,只需要一个yiled关键字。

生成器一定是迭代器(反之不成立),因此任何生成器也是以一种懒加载的模式生成值。用生成器来实现斐波那契数列的例子是:

def fib():
    prev, curr = 0, 1
    while True:
        yield curr
        prev, curr = curr, curr + prev

>>> f = fib()
>>> list(islice(f, 0, 10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

fib就是一个普通的python函数,它特殊的地方在于函数体中没有return关键字,函数的返回值是一个生成器对象。当执行f=fib()返回的是一个生成器对象,此时函数体中的代码并不会执行,只有显示或隐示地调用next的时候才会真正执行里面的代码。

生成器在Python中是一个非常强大的编程结构,可以用更少地中间变量写流式代码,此外,相比其它容器对象它更能节省内存和CPU,当然它可以用更少的代码来实现相似的功能。现在就可以动手重构你的代码了,但凡看到类似:

def something():
    result = []
    for ... in ...:
        result.append(x)
    return result
## 转换成生成器函数

def iter_something():
    for ... in ...:
        yield x

5.生成器表达式

生成器表达式是以列表推导式的方式建立生成器的版本,但是返回的是一个生成器对象

>>> a = (a**2 for a in range(10))
>>> a
<generator object <genexpr> at 0x7f060c5a17d8>
>>> a = (a**3 for a in range(10))
>>> a
<generator object <genexpr> at 0x7f0607ea83b8>
>>> a = (a for a in range(10))
>>> a
<generator object <genexpr> at 0x7f060c5a17d8>


>>> a = [a**3 for a in range(10)]
>>> a
[0, 1, 8, 27, 64, 125, 216, 343, 512, 729]
>>> b = tuple(a)
>>> b
(0, 1, 8, 27, 64, 125, 216, 343, 512, 729)
image