17. 对迭代器进行切片

╰+攻爆jí腚メ 2023-06-02 15:57 71阅读 0赞

例如, 有某个文本文件,想读取其中某范围的内容,如100 ~ 300行之间的内容,python中文件是可迭代对象。

要求:使用类似列表切片的方式得到一个100 ~ 300行文件内容的生成器。

解决方案:

使用itertools.islice()函数,它能返回一个迭代对象切片的生成器。


  • 对于列表切片:

    l = list(range(10))

    l
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    l[3]
    3

    l[2:8]
    [2, 3, 4, 5, 6, 7]

    l[2:8:2]
    [2, 4, 6]

    l.getitem(3)
    3

    l.getitem(slice(2, 8))
    [2, 3, 4, 5, 6, 7]

    l.getitem(slice(2, 8, 2))
    [2, 4, 6]

在Python中对list引用元素和形式优雅简洁的切片操作都是由解释器调用的list.__getitem__()特殊方法。

对于取单个值,list[x]等同于list.__getitem__(x);对于切片,list[start, end, step]等同于list.__getitem__(slice(start, end, step)),默认step为1。

  • 对于itertools.islice()函数:

    itertools.islice(iterable, start, stop[, step])

创建一个迭代器,返回从iterable里选中的元素。如果start不是0,跳过iterable中的元素,直到到达start这个位置。之后迭代器连续返回元素,step默认为1,除非step设置的值很高导致被跳过。

如果stop为 None,迭代器耗光为止;否则会在指定的位置停止。与普通的切片不同,islice()不支持将startstopstep设为负值。

  • 对于enumerate()函数:

    enumerate(iterable, start=0)

    l = [‘a’, ‘b’, ‘c’, ‘d’, ‘e’]

    list(enumerate(l))
    [(0, ‘a’), (1, ‘b’), (2, ‘c’), (3, ‘d’), (4, ‘e’)]

enumerate()函数返回一个枚举对象。iterable必须是一个序列,或迭代器,或其他支持迭代的对象。

enumerate()返回的迭代器的__next__()方法返回一个元组,里面包含一个计数值(从start开始,默认为0)和通过迭代iterable获得的值。


  • 方案示例:

    from itertools import islice

    f = open(‘/var/log/messages’)

    for line in islice(f, 100-1, 300): #islice()默认从0开始计数

    1. print(line)

如果是将文本文件通过readlines()函数转换为列表,然后再通过列表切片读取其中部分内容,这样当文本文件很大时则会浪费大量内存。

相比之下,通过itertools.islice()创建一个生成器进行切片截取文本文件的内容更合适简便。


  • 实现简单的my_islice()函数:

    from itertools import islice

    def my_islice(iterable, start, end, step=1):

    1. tmp = 0
    2. for i,x in enumerate(iterable):
    3. if i >= end:
    4. break
    5. if i >= start:
    6. if tmp == 0:
    7. tmp = step
    8. yield x
    9. tmp -= 1

    print(list(islice(range(50, 100), 10, 30, 3)))
    print(list(my_islice(range(50, 100), 10, 30, 3)))

    [60, 63, 66, 69, 72, 75, 78] #结果
    [60, 63, 66, 69, 72, 75, 78]


发表评论

表情:
评论列表 (有 0 条评论,71人围观)

还没有评论,来说两句吧...

相关阅读

    相关

    Java中有的多的集合,他们的底层数据结构是不同的,因此在集合遍历的时候采取的方式也各不相同,迭代器抽取出了集合的共有功能,出现了Iterator接口。在遍历集合的时候不用在意

    相关

    c++专门为一些容器vector以及string等设置了一种很好用的访问方法,就是迭代器。 迭代器是一种类似指针的操作,迭代器支持从一个位置转换到另一个位置,以

    相关

    除了使用下标来访问vector对象元素外,标准库还提供了另一种访问元素的方法:使用迭代器(iterator)。迭代器是一种检查容器内元素并遍历元素的数据类型。 标准库为每一种

    相关

    11.Iterator iterator():返回在该集合的元素上进行迭代的迭代器,用于遍历该集合所有元素。 boolean hasNext() E next()

    相关

    1. 什么是迭代器? 什么是迭代: 迭代是取数据的过程.先判断集合中是否有数据,如果有,就取出一个数据,接着再判断集合中是否有数据, 如果有再接着取出一个数据,这样往复