Python高级特性-迭代(Iteration)-列表生成式-生成器
来源:互联网 发布:淘宝宝贝降权多久恢复 编辑:程序博客网 时间:2024/06/11 15:29
迭代
定义
用for
循环对list或tuple进行遍历我们称之为迭代(Iteration)
- 只要属于list类型的对象都可以被迭代.
- Python的
for
循环抽象程度要比Java的高,迭代不仅可以用在list或tuple上还可以用在其他迭代对象上.比如dict,str.
>>> d = {'a':1,'b':2,'c':3}>>> for x in d:... print x... acb>>> str = 'abc'>>> for s in str:... print s... abc
dict是无序的所以输出结果也无序.dict默认迭代的是key,如果要迭代value呢?可以使用for value in d.itervalues()
,如果需要同时迭代key和value可以用for k, v in d.iteritems()
.
- 但是如何判断一个对象是否是可迭代对象呢?我们可以通过collection模块里的Iterable类进行判断.
>>> from collections import Iterable>>> isinstance('abc',Iterable)True>>> isinstance((1,2,3),Iterable)True>>> isinstance([1,2,3],Iterable)True>>> isinstance(123,Iterable)False
for
可以同时迭代两个变量
>>> for x,y in ((1,1),(2,2),(3,3)):... print x ,y ... 1 12 23 3
开拓思维要是需要迭代2个以上的对象呢?
>>> for a,b,c in [(1,1,1),(2,2,2),(3,3,3)]:... print a,b,c... 1 1 12 2 23 3 3
列表生成式
定义
列表生成式是Python内置的非常强大的可以用来创建list的生成式
例:生成[1…10]的list
>>> range(1,11)[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
但是如果生成[1x1,2x2,3x3….10x10]的list怎么办?
方法1:循环
>>> for x in range(1,11):... y = x * x... L.append(y)... >>> L[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]>>>
方法2:列表生成式
>>> [x*x for x in range(1,11)][1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
x*x
代表目标list的元素要放在最前面,后面就是跟for
循环取值然后赋值给x
带入x*x
进行运算.
生成式的其它用法
for
循环后添加if
判断
>>> [x*x for x in range(1,11) if x%2 == 0] #筛选出偶数[4, 16, 36, 64, 100]>>> [x*x for x in range(1,11) if x%2 != 0] #筛选出奇数[1, 9, 25, 49, 81]#只输出符合if语句的内容
- 两层循环
>>> [m + n for m in 'abc' for n in '123']['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']>>> [m + n for m in ['a','b','c'] for n in [1,2,3]]Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: cannot concatenate 'str' and 'int' objects>>> [m + n for m in ('a','b','c') for n in (1,2,3)]Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: cannot concatenate 'str' and 'int' objects#只能对同类型的数据进行组合>>> [m + n for m in ('a','b','c') for n in ('1','2','3')]['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']>>> [m + n for m in ['a','b','c'] for n in ['1','2','3']]['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']>>> [m + n for m in [1,2,3] for n in [4,5,6]][5, 6, 7, 6, 7, 8, 7, 8, 9] #以m为基础进行求和,逐次运行.
三层及三层以上的循环基本用不到了.
生成器
定义
所谓生成器就是列表生成器的进化版本:
列表生成器虽然方便创建数组但是也会占用大量内存,如果生成的数组太大,内存就会溢出,有什么好的解决办法呢?生成器(generator)就横空出世了!
生成器会根据数组推算后续数值,一边循环一边计算,这样就不会占用大量空间.
那么问题来了,怎么创建生成器呢?非常简单,把列表生成器的中括号[]
改为小括号就可以了()
>>> [x for x in range(10)][0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>>> (x for x in range(10))<generator object <genexpr> at 0x7fea306baa50> #后面0x..是generator对象的内存地址.
通过上面的代码我们可以看到,生成器不会直接生成列表只是占用一点内存空间,若是需要输出数值有两个方法:一个是直接调用生成器的next()方法;二是通过for
循环.
方法1:
>>> g = (x for x in range(10))>>> g.next()0>>> g.next()1>>> g.next()2>>> g.next()3>>> g.next()4>>> g.next()5>>> g.next()6>>> g.next()7>>> g.next()8>>> g.next()9>>> g.next()Traceback (most recent call last): #循环完毕跳出error File "<stdin>", line 1, in <module>StopIteration
方法2:
>>> g = (x for x in range(10))>>> for x in g:... print x... 0123456789>>> g.next()Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration#单个输出数值>>> g = (x for x in range(10))>>> l = []>>> for x in g:... l.append(x)... >>> l[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>>> g.next()Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration# 直接生成list>>> [x for x in range(10)][0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>>> [x for x in range(10)][0, 1, 2, 3, 4, 5, 6, 7, 8, 9]# 列表生成器可以重复执行
通过比较方法1和方法2,方法2较方法1更方便,尤其是需要计算的数组比较大的时候.
另外细心的朋友估计能发现,不像列表生成器一样可以重复输出数组.
生成器是一种线性迭代是一次性的不能回头滴.撞了南墙也回不了头啊~只能说句say you error.
更加强大的generator
碰到更复杂的算法的时候,生成器的for
循环就不能胜任了,这时候就要请出我们的函数君来解决问题.
以著名的斐波拉契数列(Fibonacci)来举例子吧.
**说明**Fibonacci数列是怎么一回事儿呢? 除了它的第一个和第二个数相等,任意一个数都可以由前面两个数相加得到.
1,1,2,3,5,8,13,21,….
普通文艺函数君:
>>> def fib(n):... i,a,b = 0,0,1... while i < n:... print b # print b 要放在公式的前面执行.... a, b = b, a+b... i = i + 1... >>> fib(5)11235>>> def fib(n):... i,a,b = 0,0,1... while i < n:... print b... a, b = b, a+b... i = i + 1... print 'new: ',b #添加一个放在后面的... >>> fib(5)1new: 11new: 22new: 33new: 55new: 8# 比较一下输出结果,得出的是(n+1)位的结果.
有可能有一部分同学已经迷糊了~这a , b, a+b,到底咋回事?
其实很好理解,我们先在Fibonacci数列前加个0,
> a b a+b # 第一次循环n=0的时候,a,b,a+b相对应的数值> 0, 1, 1, 2, 3, 5, 8> a b a+b # 第二次循环n=1的时候,a,b,a+b相对应的数值
通过上面内容我们可以看到a,b,a+b是整体逐次步进的,再去对应下代码,是不是非常好理解~
理解之后我们发现,fib
函数也是从第一个元素开始推算后续任意元素的,这个和generator的逻辑非常相似,所以我对普通文艺函数君稍微改造下就可能把他变为逗比generator函数君.
怎么改造呢?只要把fib
函数里面的print b
改为yield b
就可以了!是高富帅还是吊丝就是一步之遥啊.
逗比generator函数君:
>>> def fib(n):... i,a,b = 0,0,1... while i < n:... yield b... a, b = b, a+b... i = i + 1... >>> fib(5)<generator object fib at 0x7f29e33c9af0># 就是不输出,占坑不拉,你咬我啊.
怎么输出呢?
>>> f = fib(5)>>> f.next()1>>> f.next()1>>> f.next()2>>> f.next()3>>> f.next()5>>> f.next()Traceback (most recent call last): File "<stdin>", line 1, in <module>StopIteration# next()方法单个输出>>> for n in fib(5):... print n... 11235# for循环一次性输出
yield
和print
有啥区别呢?可以这么理解yield
,只能通过next()
或for
循环来调用,在调用的过程中边运行边计算,当函数在循环过程中碰到yield
就会输出一个数值.直到循环结束没有yield
了然后返回一个error,当然只有使用next()
方法的时候才会返回error,使用for
循环的时候没有error返回.
- Python高级特性-迭代(Iteration)-列表生成式-生成器
- 7.python高级特性:切片,迭代,列表生成式,生成器,迭代器
- Python高级特性:切片;迭代;列表生成式;生成器;迭代器
- Python高级特性(切片 迭代 列表生成式 生成器 迭代器)学习笔记
- python切片、迭代、生成器、列表生成式等高级特性学习
- Python高级特性(切片,迭代,列表生成式、生成器、迭代器)
- 转载:Python高级特性 迭代(Iteration)
- python2.7学习笔记(6) ——高级特性:切片、迭代、列表生成式、生成器
- Python(八)切片、迭代、列表生成式、生成器
- 初学python:切片、迭代、列表生成式、生成器
- python——切片 迭代 列表生成式 生成器
- Python 高级特性 : 列表生成器
- python学习笔记(7)-高级特性(三)-列表生成式与生成器
- Python3 基础:高级特性-列表生成式和生成器
- Python 迭代(iteration)
- Python中的列表生成器与高级特性
- Python 高级特性之列表生成式
- python高级特性之列表生成式
- 以非gradle方式将 Eclipse 项目导入Android Studio
- 透過Ajax技術模擬Server push功能
- UESTC -- 841 休生伤杜景死惊开(树状数组 逆序数)
- 数组在函数中的传值方法
- C#日志类,文件操作
- Python高级特性-迭代(Iteration)-列表生成式-生成器
- p124 第三章 第45题 潘璠
- 新浪微博,用SDk测试获取用户授权的问题
- 欢迎使用CSDN-markdown编辑器
- 约瑟夫循环
- Java dynamic web module和对应的TOMCAT版本
- CPP 1258 剪花布条
- 将Eclipse代码导入到AndroidStudio的两种方式
- 【DP】zoj3164