第三章:算法-itertools:迭代器函数-合并和分解迭代器

3.2 itertools:迭代器函数
itertools包括一组用于处理序列数据集的函数。这个模块提供的函数是受函数式编程语言(如Clojure,Haskell,APL和SML)中类似特性的启发。其目的是要能快速处理,以及要高效地使用内存,而且可以联结在一起表述更复制的基于迭代的算法。
与使用列表的代码相比,基于迭代器的代码可以提供更好的内存消费特性。在真正需要数据之前,并不从迭代器生成数据,由于这个原因,不需要把所有数据都同时存储在内存中。这种“懒”处理模式可以减少交换及大数据集的其他副作用,从而改善性能。
除了itertools中定义的函数,这一节中的例子还会利用一些内置函数完成迭代。

3.2.1 合并和分解迭代器
chain()函数取多个迭代器作为参数,最后返回一个迭代器,它会生成所有输入迭代器的内容,就好像这些内容来自一个迭代器一样。

from itertools import *

for i in chain([1,2,3],['a','b','c']):
    print(i ,end=' ')
print()

利用chain(),可以轻松地处理多个序列而不必构造一个很大的列表。
运行结果:

1 2 3 a b c

如果不能提前知道所有要结合的迭代器(可迭代对象),或者如果需要采用懒方式计算,那么可以使用chain.from_iterable()来构造这个链。

from itertools import *

def make_iterables_to_chain():
    yield [1,2,3]
    yield ['a','b','c']


for i in chain.from_iterable(make_iterables_to_chain()):
    print(i,end=' ')
print()

运行结果:

1 2 3 a b c

内置函数zip()返回一个迭代器,它会把多个迭代器的元素结合到一个元组中。

for i in zip([1,2,3],['a','b','c']):
    print(i)

与这个模块中的其他函数一样,返回值是一个可迭代的对象,会一次生成一个值。
运行结果:

(1, ‘a’)
(2, ‘b’)
(3, ‘c’)

第一个输入迭代器处理完时zip()就会停止。要处理所有输入(即使迭代器生成的值个数不同),则要使用zip_longest().

from itertools import *

r1 = range(3)
r2 = range(2)

print('zip stops early:')
print(list(zip(r1,r2)))

r1 = range(3)
r2 = range(2)

print('\nzip_longest processes all of the values:')
print(list(zip_longest(r1,r2)))

默认地,zip_longest()会把所有缺少的值替换为None。可以借助fillvalue参数来使用一个不同的替换值。
运行结果:

zip stops early:
[(0, 0), (1, 1)]

zip_longest processes all of the values:
[(0, 0), (1, 1), (2, None)]

islice()函数返回一个迭代器,它按索引从迭代器返回所选择的元素。

from itertools import *

print('Stop at 5:')
for i in islice(range(100),5):
    print(i,end=' ')
print('\n')

print('Start at 5,Stop at 10:')
for i in islice(range(100),5,10):
    print(i,end=' ')
print('\n')

print('By tens to 100:')
for i in islice(range(100),0,100,10):
    print(i,end=' ')
print('\n')

islice()与列表的slice操作符参数相同,同样包括开始位置(start),结束位置(stop)和步长(step)。start和step参数是可选的。
运行结果:

Stop at 5:
0 1 2 3 4

Start at 5,Stop at 10:
5 6 7 8 9

By tens to 100:
0 10 20 30 40 50 60 70 80 90

tee()函数根据一个原输入迭代器返回多个独立的迭代器(默认为2个)。

from itertools import *

r = islice(count(),5)
i1,i2 = tee(r)

print('i1:',list(i1))
print('i2:',list(i2))

tee()的语义类似于UNIX tee工具,它会重复从输入读到的值,并把它们写至一个命名文件和标准输出。tee()返回的迭代器可以用来为并行处理的多个算法提供相同的数据集。
运行结果:

i1: [0, 1, 2, 3, 4]
i2: [0, 1, 2, 3, 4]

tee()创建的新迭代器会共享输入迭代器,所以创建了新迭代器后,不应再使用原迭代器。

from itertools import *

r = islice(count(),5)
i1 ,i2 = tee(r)

print('r:',end=' ')
for i in r:
    print(i,end=' ')
    if i > 1:
        break
print()

print('i1:',list(i1))
print('i2:',list(i2))

如果原输入迭代器的一些值已经消费,新迭代器不会再生成这些值。
运行结果:

r: 0 1 2
i1: [3, 4]
i2: [3, 4]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值