Python高级特性:切片、列表生成式、生成器、迭代器

Python高级特性

一、切片

list = [1,2,3,4,5,6,7]
# 包含起点,不包含终点
list1 = list[1:3]
# list1 = [2,3]
# :前后可省略
list2 = list[2:]
# list2 = [3,4,5,6,7]

二、列表生成式

# 列表生成式
list = list(range(1, 11))
print(list)
#
# 把要生成的元素 x * x 放前面,后面跟for循环,就可以生成list了
list1 = [x * x for x in range(1, 11)]
print(list1)

# 还可以把判断加上,例如筛选出仅偶数的平方
list2 = [x * x for x in range(1, 11) if x % 2 == 0]
print(list2)

# 还可以使用两层循环,生成全排列,例如:
list3 = [m + n for m in 'ABC' for n in 'XYZ']
print(list3)

# 运用列表生成式,可以写出非常简洁的代码,例如,列出当前目录下所有文件和目录名,可以通过一行代码实现
# 先导头文件
import os
list4 = [d for d in os.listdir('.')]
print(list4)

# 列表生成式可以用两个变量来生成list
d = {'x': 'A', 'y': 'B', 'z': 'C' }
list5 = [k + '=' + v for k, v in d.items()]
print(list5)

# 把一个list中所有字符串变成小写
L = ['Hello', 'World', 'IBM', 'Apple']
list6 = [s.lower() for s in L]
print(list6)

三、生成器

原理:


# 通过列表生成式,我们可以直接创建一个列表。


# 但是,受到内存限制,列表容量肯定是有限的。


# 而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,


# 如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。


# 所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?


# 这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。

创建生成器的方式有以下几种

  • 最简单的创建生成器的方式,只需要把列表生成式的[]换成()就可以了

    generator = (x * x for x in range(1, 11))

  • 第二种函数式创建generator,举一个简单的例子:斐波拉契数列

    def fib(max):
      n, a, b = 0, 0, 1
      while n < max:
          yield b
          a, b = b, a + b
          n += 1
      return 'done'
    print(fib(10))
    
    for n in fib(10):
      print(n)
    
    #得出的结果是这样
    
    1
    1
    2
    3
    5
    8
    13
    21
    34
    55

    '''
    但是用for循环调用generator时,发现拿不到generator的return语句的返回值。
    如果想要拿到返回值,必须捕获StopIteration错误,返回值包含在StopIteration的value中:
    '''
    g = fib(10)
    while True:
      try:
          x = next(g)
          print('g:', x)
      except StopIteration as e:
          print('Generator return value:', e.value)
          break

    用生成器实现杨辉三角:

    原理:把每一行看成一个list,不断输出下一行list

    def triangles():
      n = 0
      list = []
      listold = []
      while True:
          for i in range(n):
              if n == 1:
                  list.append(1)
              else:
                  if i == len(list):
                      list.append(1)
                  else:
                      if i < len(list) - 1:
                          list[i + 1] = listold[i] + listold[i + 1]
    
          yield list
          listold = list.copy()
          n += 1
      return 'done'
    m = 0
    for t in triangles():
      print(t)
      m = m + 1
      if m == 10:
          break

四、迭代器

from collections import Iterator
'''
所有的list,dict,str等,可用for循环的数据类型,都称之为可迭代对象:Iterable
但是只有可以被next()函数调用,并不断返回下一个值的对象称为迭代器:Iterator
'''
# 判断某个值是否是某个类型,可以用函数:
print(isinstance('aaa', str))
print(isinstance([], Iterator))
'''
为什么list,dict, str,等数据类型不是Iterator?

这是因为Python的Iterator对象表示的是一个数据流,
Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。
可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,
所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。
'''
# 想把list,dict,str等变成Iterator,需要用Iter()函数
from collections import Iterator
print(isinstance(iter([]), Iterator))
'''
迭代器小结:
1、凡是可作用于for循环的对象都是Iterable类型;

2、凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

3、集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

4、Python的for循环本质上就是通过不断调用next()函数实现的
'''
# 关于第四点举个简单的例子
for i in [1,2,3,4,5,6]:
    pass
# 完全等价于:
it = iter([1,2,3,4,5,6])
while True:
    try:
        x = next(it)
    except StopIteration:
        break

猜你喜欢

转载自blog.csdn.net/qq_35612929/article/details/81098950
今日推荐