迭代和推导

迭代相关的概念

可迭代对象: 如果对象是实际保存的序列或者可以在迭代工具上下文中一次只生成一个结果的对象, 那么就可以看做是可迭代的

完整的迭代协议:

  • 可迭代对象: 迭代的被调对象,其 __iter__方法被iter函数所调用
  • 迭代器对象: 可迭代对象返回的结果在迭代过程中实际提供对象的值, 它的__next__方法被next运行并在结束时触发StoperInteration异常

迭代器:所有带有__next__方法的对象会前进到下一个结果,而达到一系列结果的末尾时,__next__会引发StopInteration异常,这种对象在Python中称为迭代器

for line in open('test.py'):
    print(line.Upper(), end='')

迭代器对象支持一次迭代,而列表或者其他内置对象自身不是迭代器,可以支持多次迭代,可迭代对象必须要调用iter来启动迭代

在最新的Python版本中,字典作为一个可迭代对象自带一个迭代器,在迭代上下文中,会自动一次返回一个键

D = { 'a':1, 'b':2, 'c':3}
for key in D.keys():
    print(key, D[key])
 
 I = iter(D)
 next(I)

 next(I)

列表推导

# for 循环语句
L = [1, 2, 3, 4]
for i in range(len(L)):
    L[i] += 10

# 列表推导
L = [x + 10 for x in L]

列表推导基础

列表推导比for循环快,是因为列表推导的迭代在解释器内部是以C语言速度执行的


[line.rstrip().upper() for line in open('test.txt')]
[line.rstrip().upper() for line in open('test.txt') if line[0] == 'p']
[x + y for x in 'abc' for y in 'cdf']
# Range 返回可迭代对象, Range只支持迭代,索引以及len函数
len(R)
next(R)
# map, zip, filter 是一个迭代器,只能迭代一次,如果需要列表的话,需要用list方法来强制转化
M = list(map(abs, (-1, 0, 1)))
N = zip((1, 2, 3,4,5), (10, 20, 39))
B = list(filter(bool, ['spam', '', 'test']))
print(B) # ['spam', 'test']

# map, zip, filter 不支持同一个结果上的多个活动迭代器
Z = N = zip((1, 2, 3), (10, 20, 39))

I1 = iter(Z)
I2 = iter(Z)

next(I1) # (1, 10)
next(I2) # (2, 20)

在编写自己的可迭代对象时, 通常采用调用iter来返回一个新的可迭代对象的方式,来支持多次迭代

posted @ 2021-12-24 17:14  焰红火  阅读(88)  评论(0)    收藏  举报