Python基础(08):迭代器和解析

迭代器是一个可以记住遍历的位置的对象。

迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

一、NEXT

  • 语法:next(iterator[, default])

  • 说明:

    • 函数必须接收一个可迭代对象参数,每次调用的时候,返回可迭代对象的下一个元素。如果所有元素均已经返回过,则抛出StopIteration 异常。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      >>> a = iter('abcd')
      >>> next(a)
      'a'
      >>> next(a)
      'b'
      >>> next(a)
      'c'
      >>> next(a)
      'd'
    • 函数可以接收一个可选的default参数,传入default参数后,如果可迭代对象还有元素没有返回,则依次返回其元素值,如果所有元素已经返回,则返回default指定的默认值而不抛出StopIteration 异常。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      = iter('abcd')
      >>> next(a,'e')
      'a'
      >>> next(a,'e')
      'b'
      >>> next(a,'e')
      'c'
      >>> next(a,'e')
      'd'
      >>> next(a,'e')
      'e'
      >>> next(a,'e')
      'e'

二、iter

  • 语法:iter(object[, sentinel])

  • 说明:

    • 函数功能返回一个可迭代对象。

    • 当第二个参数不提供时,第一个参数必须是一个支持可迭代协议(即实现了__iter__()方法)的集合(字典、集合、不可变集合),或者支持序列协议(即实现了__getitem__()方法,方法接收一个从0开始的整数参数)的序列(元组、列表、字符串),否则将报错。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      >>> a = iter({'A':1,'B':2}) #字典集合
      >>> a
      <dict_keyiterator object at 0x03FB8A50>
      >>> next(a)
      'A'
      >>> next(a)
      'B'
        
      >>> a = iter('abcd'#字符串序列
      >>> a
      <str_iterator object at 0x03FB4FB0>
      >>> next(a)
      'a'
      >>> next(a)
      'b'
      >>> next(a)
      'c'
      >>> next(a)
      'd'
    • 当第二个参数sentinel提供时,第一个参数必须是一个可被调用对象。创建的迭代对象,在调用__next__方法的时候会调用这个可被调用对象,当返回值和sentinel值相等时,将抛出StopIteration异常, 终止迭代。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      >>> class IterTest:
          def __init__(self):
              self.start = 0
              self.end = 10
          def get_next_value(self):
              current = self.start
              if current < self.end:
                  self.start += 1
              else:
                  raise StopIteration
              return current
               
      >>> iterTest = IterTest() #实例化类
      >>> a = iter(iterTest.get_next_value,4# iterTest.get_next_value为可调用对象,sentinel值为4
      >>> a
      <callable_iterator object at 0x03078D30>
      >>> next(a)
      >>> next(a)
      1
      >>> next(a)
      2
      >>> next(a)
      3

三、RANGE

  • 语法:range(start, stop[, step])

  • 说明:

    • range函数用于生成一个range对象,range类型是一个表示整数范围的类型。

    • 可以直接传入一个结束整数来初始化一个range类型,默认起始值为0(包含0).结束整数可以大于0,也可以小于等于0,但是小于等于0的时候生成的range对象实际是不包含任何元素的。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      >>> a = range(5)
      >>> a
      range(05)
      >>> len(a)
      5
      >>> for in a:print(x)
        
      1
      2
      3
      4
        
      >>> b = range(0# 传入0,空range对象
      >>> len(b)
        
      >>> c = range(-5)  # 传入负数,空range对象
      >>> len(c)
    • 可以传入一个起始整数和一个结束整数来初始化一个range类型,生成的range类型包含起始整数(包含),和结束整数(不包含)之间的所有整数。

      1
      2
      3
      4
      5
      6
      7
      8
      >>> a = range(1,5)
      >>> a
      range(15)
      >>> for in a:print(x)
      1
      2
      3
      4
    • 传入了起始整数和结束整数,还可以同时传入一个步进值来初始化一个range类型,生成的range类型包含起始整数(包含),和结束整数(不包含)之间的以步进值筛选后的整数。

      1
      2
      3
      4
      5
      6
      7
      >>> a = range(1,10,3)
      >>> a
      range(1103)
      >>> for in a:print(x)
      1
      4
      7
    • 初始化range类型时起始整数和结束整数,遵循的是左臂右开原则,即包含起始整数,但不包含结束整数。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      >>> a = range(1,5)
      >>> a
      range(15)
      >>> for in a:print(x) # 包含1,不包含5
        
      1
      2
      3
      4
    • range接收的参数都必须是整数,不能是浮点数等其它数据类型。

    • range实际上是一个不可变的序列类型,可以对它进行取元素、切片等序列操作,但是不能对其中元素修改值。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      >>> a = range(1,5)
        
      >>> a[0# 取元素
      1
      >>> a[:-2# 切片
      range(13)
      >>> a[1= 2 # 修改元素值
      Traceback (most recent call last):
        File "<pyshell#38>", line 1in <module>
          a[1= 2
      TypeError: 'range' object does not support item assignment

四、MAP

  • 语法:map(function, iterable, …)

  • 说明:

    • 函数接受一个函数类型参数、一个或者多个可迭代对象参数,返回一个可迭代器,此迭代器中每个元素,均是函数参数实例调用可迭代对象后的结果。

      1
      2
      3
      4
      5
      >>> a = map(ord,'abcd')
      >>> a
      <map object at 0x03994E50>
      >>> list(a)
      [979899100]
    • 当传入多个可迭代对象时,函数的参数必须提供足够多的参数,保证每个可迭代对象同一索引的值均能正确传入函数。

      1
      2
      3
      4
      5
      6
      >>> a = map(ord,'abcd','efg'# 传入两个可迭代对象,所以传入的函数必须能接收2个参数,ord不能接收2个参数,所以报错
      >>> list(a)
      Traceback (most recent call last):
        File "<pyshell#22>", line 1in <module>
          list(a)
      TypeError: ord() takes exactly one argument (2 given)
    • 当传入多个可迭代对象时,且它们元素长度不一致时,生成的迭代器只到最短长度。

      1
      2
      3
      4
      5
      6
      7
      >>> def f(a,b):
          return + b
           
      >>> a = map(f,'abcd','efg'# 选取最短长度为3
      >>> list(a)
      ['ae''bf''cg']
      map函数是一个典型的函数式编程例子。

五、ZIP

  • 语法:zip(*iterables)

  • 说明:

    • 函数功能是聚合传入的每个迭代器中相同位置的元素,返回一个新的元组类型迭代器。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      >>> x = [1,2,3]
      >>> y = [4,5,6]
      >>> xy = zip(x,y)
      >>> xy #xy的类型是zip类型
      <zip object at 0x0429C828>
      #导入Iterable
      >>> from collections import Iterable
      >>> isinstance(xy,Iterable) #判断是否可迭代对象
      True
      >>> list(xy) #结果
      [(14), (25), (36)]
    • 如果传入的迭代器长度不一致,最短长度的迭代器迭代结束后停止聚合。

      1
      2
      3
      4
      >>> x = [1,2,3#长度3
      >>> y = [4,5,6,7,8#长度5
      >>> list(zip(x,y)) # 取最小长度3
      [(14), (25), (36)]
    • 如果只传入一个迭代器,则返回的单个元素元组的迭代器。

      1
      2
      >>> list(zip([1,2,3]))
      [(1,), (2,), (3,)]
    • 如果不传入参数,则返回空的迭代器。

      1
      2
      >>> list(zip())
      []
    • zip(*[iter(s)]*n)等效于调用zip(iter(s),iter(s),…,iter(s))。

      1
      2
      3
      4
      5
      6
      7
      >>> x = [1,2,3]
        
      >>> list(zip(*[x]*3))
      [(111), (222), (333)]
        
      >>> list(zip(x,x,x))
      [(111), (222), (333)]

六、FILTER

  • 语法:filter(function, iterable)

  • 说明:

    • filter函数用于过滤序列。过滤的方式则是采用传入的函数,去循环序列的元素调用,如果函数计算的结果为True则保留元素,否则将舍弃该元素。

      1
      2
      3
      4
      5
      6
      7
      8
      >>> a = list(range(1,10)) #定义序列
      >>> a
      [123456789]
      >>> def if_odd(x): #定义奇数判断函数
          return x%2==1
           
      >>> list(filter(if_odd,a)) #筛选序列中的奇数
      [13579]
    • 当function参数传入None时,序列中的元素值如果为False,也会自动舍弃。

      1
      2
      3
      4
      5
      6
      >>> c = ['',False,'I',{}] #定义序列
      >>> c
      ['', False, 'I', {}]
        
      >>> list(filter(None,c)) #筛选函数为None,自动舍弃序列中的False值,空字符串、False值、空序列都是False值,所以丢弃
      ['I']

七、LIST类型迭代

1
2
3
4
5
6
7
8
>>> L = [1,2,3,4,5]
>>> for in range(len(L)):
>>>    L[i] += 10
>>> print(L)
[1112131415]
>>> L = [x + 10 for in L]
>>> print(L)
[2122232425]

八、DICT类型迭代

1
2
3
>>> D = dict(a=1, b=2, ,c=3)
>>> for in sorted(D): print(k, D[k], end=' ')
1 2 3

发表评论