python学习笔记の高级特性:切片、迭代、列表生成式、生成器、迭代器

切片
在很多编程语言中,针对字符串提供了很多各种截取函数(例如,substring),其实目的就是对字符串切片。Python没有针对字符串的截取函数,只需要切片一个操作就可以完成,非常简单。

我们先创建一个0-99的数列:
>>> L = list(range( 100 )) >>> L[ 0 , 1 , 2 , 3 , ..., 99 ]
可以通过切片轻松取出某一段数列。比如前10个数:
>>> L [:10][0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
后10个数:
>>> L [-10:][90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
前11-20个数:
>>> L [10:20][10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
前10个数,每两个取一个:
>>> L [:10:2][0, 2, 4, 6, 8]
所有数,每5个取一个:
>>> L [::5][0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
甚至什么都不写,只写 [:] 就可以原样复制一个list:
>>> L [:][0, 1, 2, 3, ..., 99]

迭代
>>> d = { 'a' : 1 , 'b' : 2 , 'c' : 3 } >>> for key in d: ... print(key)...acb
dict迭代的是key。如果要迭代value,可以用 for value in d.values() ,如果要同时迭代key和value,可以用 for k, v in d.items()

当我们使用 for 循环时,只要作用于一个可迭代对象, for 循环就可以正常运行,而我们不太关心该对象究竟是list还是其他数据类型。
那么, 如何判断一个对象是可迭代对象 呢?方法是通过collections模块的Iterable类型判断:
>>> from collections import Iterable >>> isinstance( 'abc' , Iterable) # str是否可迭代 True >>> isinstance([ 1 , 2 , 3 ], Iterable) # list是否可迭代 True >>> isinstance( 123 , Iterable) # 整数是否可迭代 False

如果要对list实现类似Java那样的下标循环怎么办?Python内置的 enumerate 函数可以把一个list变成索引-元素对,这样就可以在 for 循环中同时迭代索引和元素本身:
>>> for i, value in enumerate([ 'A' , 'B' , 'C' ]): ... print(i, value)... 0 A 1 B 2 C


列表生成式
要生成 [1x1, 2x2, 3x3, ..., 10x10] 怎么做

>>> L = [] >>> for x in range( 1 , 11 ): ... L.append(x * x)... >>> L[ 1 , 4 , 9 , 16 , 25 , 36 , 49 , 64 , 81 , 100 ]
----------------------------------------------------
>>> [x * x for x in range( 1 , 11 )][ 1 , 4 , 9 , 16 , 25 , 36 , 49 , 64 , 81 , 100 ]

还可以使用两层循环,可以生成全排列:
>>> [m + n for m in 'ABC' for n in 'XYZ' ][ 'AX' , 'AY' , 'AZ' , 'BX' , 'BY' , 'BZ' , 'CX' , 'CY' , 'CZ' ]

写列表生成式时,把要生成的元素 x * x 放到前面,后面跟 for 循环,就可以把list创建出来,十分有用,多写几次,很快就可以熟悉这种语法。
for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:
>>> [x * x for x in range( 1 , 11 ) if x % 2 == 0 ][ 4 , 16 , 36 , 64 , 100 ]

生产器
通过列表生成式,我们可以直接创建一个 列表 。但是, 受到内存限制 ,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不 必创建完整的list ,从而节省大量的空间。在Python中, 这种一边循环一边计算的机制,称为生成器:generator
要创建一个generator,有很多种方法。
第一种方法很简单,只要把一个列表生成式的 [] 改成 () ,就创建了一个generator:
>> L = [x * x for x in range( 10 )] >>> L[ 0 , 1 , 4 , 9 , 16 , 25 , 36 , 49 , 64 , 81 ] >>> g = (x * x for x in range( 10 )) >>> g<generator object <genexpr> at 0x1022ef630 >
--------------------------------------------
第一种方法:如果一个函数定义中包含 yield 关键字,那么这个函数就不再是一个普通函数,而是一个generator
def fib (max): n, a, b = 0 , 0 , 1 while n < max: yield b a, b = b, a + b n = n + 1 return 'done'

迭代器
我们已经知道,可以直接作用于 for 循环的数据类型有以下几种:
一类是集合数据类型,如 list tuple dict set str 等;
一类是 generator ,包括生成器和带 yield 的generator function。
这些可以直接作用于 for 循环的对象统称为可迭代对象: Iterable
可以使用 isinstance() 判断一个对象是否是 Iterable 对象:

>>> from collections import Iterable >>> isinstance([], Iterable) True

在Python中,这种一边循环一边计算的机制,称为生成器:generator。
当循环完之后,生成器里面就没有了
因为她是一个推算方法,用完一次,就不能再用了 里面就空了
生产器都是Iterator
但是集合类型 list dict str 等虽然是Iterable的但是不是Iterator


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值