python将list转换为迭代器代码_探索Python可迭代对象,迭代器和生成器(PART1)

感觉在Python中,”迭代”是个很重要的关键词,而且Python3将所有内置函数的返回都改成了迭代器。所以Python的可迭代对象,迭代器和生成器这些知识,是时候进行一番详细的梳理了

关于”重复”的基本概念

一般程序语言中都有这样一些关于”重复”的概念,如loop、iterate、traversal 和 recursion,他们的通常的定义是:

loop(循环): 在一定条件下,重复执行同一段代码,如Python中的while;

iterate(迭代): 按照某种顺序逐个访问容器中的每一项,如Python中的for;

traversal(递归): 不断调用自身,如斐波那契数列;

recursion(遍历): 按照一定的规则访问结构中的每个节点,而且每个节点都只访问一次

通过这些定义,我们会发现Python中的for语句并不能够像别的编程语言那样实现for循环,Python的循环都是while来实现的;Python的for用来实现迭代。

关于”迭代”的基本概念

那么在Python中,关于”迭代”的概念,又有这些: iterable,iterator和generators

iterable(可迭代对象): 定义了可以返回一个迭代器的__iter__方法,或者定义了可以支持下标索引的__getitem__方法

iterator(迭代器): 定义了__next__方法

generators(生成器): 含义yield的一种特殊的迭代器

可迭代对象与迭代器的关系

那么他们之间的关系是这样的:

iter()这个函数,可以使可迭代对象转换为迭代器

详解可迭代对象和迭代器

下面稍微详细介绍一下他们

可迭代对象(Iterable)

具有__iter__ 方法,用于返回一个迭代器,或者定义了 __getitem__ 方法,可以按 index 索引的对象(并且能够在没有值时抛出一个 IndexError 异常)

可迭代对象可以通过for来迭代其中的每个元素;

可迭代对象可以通过index索引里面的每个元素(__getitem__);

可迭代对象可以通过iter()返回迭代器(__iter__);

可以通过isinstance(obj, collections.Iterable) 来判断对象是否为可迭代对象1

2

3import collections

a = 'string is iterable'

isinstance(a, collections.Iterable)

迭代器(Iterator)

含有 next (Python 2) 或者 __next__ (Python 3) 方法

定义了__next__方法返回下一个值,在结尾处抛出StopIteration

可以通过 isinstance(obj, collections.Iterator) 来判断对象是否为迭代器1

2

3

4

5

6

7import collections

a = 'string is iterable but not a iterator'

>>>isinstance(a, collections.Iterator)

False

>>>iter_a = iter(a)

>>>isinstance(iter_a, collections.Iterator)

True

for语句原理

for语句在Python中适用于迭代的,而while才是真正的循环

深究其差别在于,循环是可以增加跳过的条件的,但是迭代只能一个接着一个取值

在for语句的内部,是调用可迭代对象的iter()方法将可迭代对象转化为迭代器,然后在调用迭代器中的next()方法进行的迭代。for语句会自动捕获迭代器结束时的StopIteration异常并终止迭代。

Python的“迭代”

Python尤其是Python3之后,给人感觉尤其重视“迭代”。

我们可以看到有很多内置函数的返回都变成了迭代器,而且不止于此。

文件迭代器1

2

3

4

5

6f = open('test.txt', 'r')

f.readline()

# 返回第二行

f.readline()

...

由此可见,通过open打开的文件对象,通过readline读取的过程,就是一个迭代器不断调用__next__的过程。

os.popen和shelves对象也都是迭代器

不过这两个我目前不是很熟悉就先不写了

list和dict是可迭代对象不是迭代器

他们可以通过iter转换成迭代器1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18>>>a = [1,2]

>>>a

[1, 2]

>>>iter(a) is a

False

>>>b = {'a':1, 'b':10}

>>>iter(b) is b

False

>>>b_ = iter(b)

>>>next(b_)

'a'

>>>next(b_)

'b'

>>>next(b_)

Traceback (most recent call last):

File "", line 1, in

StopIteration

对于dict,转换成迭代器之后通过next调取到的是字典的key

关于dict.keys,dict.values和dict.items

首先,dict是可迭代对象非迭代器

dict.keys,dict.values和dict.items都是可迭代对象非迭代器

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23>>>d = dict(a=1, b=5)

>>>type(d)

>>> next(d)

Traceback (most recent call last):

File "", line 1, in

TypeError: 'dict' object is not an iterator

>>>keys_ = d.keys

>>>type(keys_)

>>> next(keys_)

Traceback (most recent call last):

File "", line 1, in

TypeError: 'builtin_function_or_method' object is not an iterator

>>>values_ = d.values

>>>values_

>>>items_ = d.items

>>>items_

enumerate()返回的是迭代器1

2

3

4

5

6

7

8>>>a = [1,2]

>>>type(enumerate(a))

>>> n = enumerate(a)

>>>n

>>>next(n)

(0, 1)

map(),zip()和filter()返回的是迭代器

map1

2

3

4

5

6

7>>>map(abs, [-1,-2,1])

>>>abs_ = map(abs, [-1,-2,1])

>>>next(abs_)

1

>>>next(abs_)

2

zip1

2

3

4

5>>>zip([1,2,3], [7,8,9])

>>>zip_ = zip([1,2,3], [7,8,9])

>>>next(zip_)

(1, 7)

filter1

2

3

4

5

6

7

8

9>>>filter(bool, [True, 1, 0, 's'])

>>>filter_ = filter(bool, [True, 1, 0, 's'])

>>>next(filter_)

True

>>>next(filter_)

1

>>>next(filter_)

's'

详解生成器

生成器(generator)

一个特殊的迭代器

任何包含 yield 语句的函数被称为生成器

惰性计算

生成器表达式有一个特点,就是 惰性计算

这里有一段代码,对理解生成器的惰性计算非常重要1

2

3

4

5

6

7

8

9

10

11

12

13

14

15def add(s, x):

return s + x

def gen():

for i in range(4):

yield i

base = gen()

for n in [1, 10]:

base = (add(i, n) for i in base)

print(list(base))

### 代码返回的是

### [20, 21, 22, 23]

有个Python代码执行的可视化网站可以帮助对这段代码进行理解

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值