Python中的列表生成式与生成器学习教程


Posted in Python onMarch 13, 2016

列表生成式
即创建列表的方式,最笨的方法就是写循环逐个生成,前面也介绍过可以使用range()函数来生成,不过只能生成线性列表,下面看看更为高级的生成方式:

>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来,十分有用,多写几次,很快就可以熟悉这种语法。
你甚至可以在后面加上if判断:

>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]

循环嵌套,全排列:

>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']

看一个简单应用,列出当前目录下所有文件和目录:

>>> import os
>>> [d for d in os.listdir('.')]
['README.md', '.git', 'image', 'os', 'lib', 'sublime-imfix', 'src']

前面也说过Python里循环中可以同时引用两个变量,所以生成变量也可以:

>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.iteritems()]
['y=B', 'x=A', 'z=C']

也可以通过一个list生成另一个list,例如把一个list中所有字符串变为小写:

>>> L = ['Hello', 'World', 'IBM', 'Apple']
>>> [s.lower() for s in L]
['hello', 'world', 'ibm', 'apple']

但是这里有个问题,list中如果有其他非字符串类型,那么lower()会报错,解决办法:

>>> L = ['Hello', 'World', 'IBM', 'Apple', 12, 34]
>>> [s.lower() if isinstance(s,str) else s for s in L]
['hello', 'world', 'ibm', 'apple', 12, 34]

此外,列表生成式还有许多神奇用法,说明请看注释:

#!/usr/bin/env python3 
# -*- coding: utf-8 -*- 
 
list(range(1, 11)) 
 
# 生成1乘1,2乘2...10乘10 
L = [] 
for x in range(1, 11): 
  L.append(x * x) 
 
# 上面太麻烦,看下面 
[x * x for x in range(1, 11)] 
# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] 
 
# 加上if,就可以筛选出仅偶数的平方 
[x * x for x in range(1, 11) if x % 2 == 0] 
# [4, 16, 36, 64, 100] 
 
# 两层循环,可以生成全排列 
[m + n for m in 'ABC' for n in 'XYZ'] 
# ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ'] 
 
# 列出当前目录下的所有文件和目录名 
import os 
[d for d in os.listdir('.')] # on.listdir可以列出文件和目录 
 
# 列表生成式也可以使用两个变量来生成list: 
d = {'x': 'A', 'y': 'B', 'z': 'C'} 
[k + '=' + v for k, v in d.items()] 
# ['x=A', 'z=C', 'y=B'] 
 
# 把一个list中所有的字符串变成小写 
L = ['Hello', 'World', 'IBM', 'Apple'] 
[s.lower() for s in L] 
# ['hello', 'world', 'ibm', 'apple'] 
 
L1 = ['Hello', 'World', 18, 'Apple', None] 
L2 = [s.lower() for s in L1 if isinstance(s, str)] 
print(L2) 
# ['hello', 'world', 'apple'] 
# isinstance函数可以判断一个变量是不是字符串

生成器
列表生成式虽然强大,但是也会有一个问题,当我们想生成一个很大的列表时,会非常耗时,并且占用很大的存储空间,关键是这里面的元素可能你只需要用到前面很少的一部分,大部分的空间和时间都浪费了。Python提供了一种边计算边使用的机制,称为生成器(Generator),创建一个Generator最简单的方法就是把[]改为():

>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x7fe73eb85cd0>

如果要一个一个打印出来,可以通过generator的next()方法:

>>> g.next()
0
>>> g.next()
1
>>> g.next()
4
>>> g.next()
9
>>> g.next()
16
>>> g.next()
25
>>> g.next()
36
>>> g.next()
49
>>> g.next()
64
>>> g.next()
81
>>> g.next()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
StopIteration

其实generator object也是可迭代的,所以可以用循环打印,还不会报错。

>>> g = (x * x for x in range(10))
>>> for n in g:
...   print n
...

这是简单的推算算法,但是如果算法比较复杂,写在()里就不太合适了,我们可以换一种方式,使用函数来实现。
比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:
1, 1, 2, 3, 5, 8, 13, 21, 34, …
斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:

def fib(max):
  n, a, b = 0, 0, 1
  while n < max:
    print b
    a, b = b, a + b
    n = n + 1

上面的函数可以输出斐波那契数列的前N个数,这个也是通过前面的数推算出后面的,所以可以把函数变成generator object,只需要把print b改为yield b即可。

def fib(max):
  n, a, b = 0, 0, 1
  while n < max:
    yield b
    a, b = b, a + b
    n = n + 1

如果一个函数定义中包含了yield关键字,这个函数就不在是普通函数,而是一个generator object。

>>> fib(6)
<generator object fib at 0x7fa1c3fcdaf0>
>>> fib(6).next()
1

所以要想调用这个函数,需要使用next()函数,并且遇到yield语句返回(可以把yield理解为return):

def odd():
  print 'step 1'
  yield 1
  print 'step 2'
  yield 3
  print 'step 3'
  yield 5

看看调用输出结果:

>>> o = odd()
>>> o.next()
step 1
1
>>> o.next()
step 2
3
>>> o.next()
step 3
5
>>> o.next()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
StopIteration

同样也可以改为for循环语句输出。例如:

def odd():
  print 'step 1'
  yield 1
  print 'step 2'
  yield 2
  print 'step 3'
  yield 3

if __name__ == '__main__':
  o = odd()
  while True:
    try:
      print o.next()
    except:
      break
Python 相关文章推荐
python多线程编程方式分析示例详解
Dec 06 Python
python正则表达式的使用
Jun 12 Python
Python 批量合并多个txt文件的实例讲解
May 08 Python
Python实现多属性排序的方法
Dec 05 Python
Django 外键的使用方法详解
Jul 19 Python
Python 通过微信控制实现app定位发送到个人服务器再转发微信服务器接收位置信息
Aug 05 Python
PyQt5中多线程模块QThread使用方法的实现
Jan 31 Python
浅谈Python的方法解析顺序(MRO)
Mar 05 Python
keras分类模型中的输入数据与标签的维度实例
Jul 03 Python
Python 利用flask搭建一个共享服务器的步骤
Dec 05 Python
如何用 Python 子进程关闭 Excel 自动化中的弹窗
May 07 Python
Python实现日志实时监测的示例详解
Apr 06 Python
jupyter安装小结
Mar 13 #Python
Ubuntu下安装PyV8
Mar 13 #Python
Python连接MySQL并使用fetchall()方法过滤特殊字符
Mar 13 #Python
深入讲解Python函数中参数的使用及默认参数的陷阱
Mar 13 #Python
编写Python小程序来统计测试脚本的关键字
Mar 12 #Python
使用Python内置的模块与函数进行不同进制的数的转换
Mar 12 #Python
Python语言的面相对象编程方式初步学习
Mar 12 #Python
You might like
php禁止浏览器使用缓存页面的方法
2014/11/07 PHP
thinkphp5.1框架实现格式化mysql时间戳为日期的方式小结
2019/10/10 PHP
将string解析为json的几种方式小结
2010/11/11 Javascript
javascript学习笔记(七) js函数介绍
2012/06/19 Javascript
js 3种归并操作的实例代码
2013/10/30 Javascript
js操作label给label赋值及取label的值示例
2013/11/07 Javascript
JS使用for循环遍历Table的所有单元格内容
2014/08/21 Javascript
将数字转换成大写的人民币表达式的js函数
2014/09/21 Javascript
5个可以帮你理解JavaScript核心闭包和作用域的小例子
2014/10/08 Javascript
Jquery实现地铁线路指示灯提示牌效果的方法
2015/03/02 Javascript
javascript实现倒计时并弹窗提示特效
2015/06/05 Javascript
基于jQuery实现的向下滑动二级菜单效果代码
2015/08/31 Javascript
jQuery简单实现tab选项卡切换效果
2016/06/20 Javascript
基于MVC+EasyUI的web开发框架之使用云打印控件C-Lodop打印页面或套打报关运单信息
2016/08/29 Javascript
jQuery布局组件EasyUI Layout使用方法详解
2017/02/28 Javascript
nodejs 终端打印进度条实例代码
2017/04/22 NodeJs
浅谈对于react-thunk中间件的简单理解
2019/05/01 Javascript
bootstrap table实现iview固定列的效果实例代码详解
2019/09/30 Javascript
[01:06]欢迎来到上海,TI9
2018/08/26 DOTA
Windows下为Python安装Matplotlib模块
2015/11/06 Python
详解Python编程中基本的数学计算使用
2016/02/04 Python
简单掌握Python的Collections模块中counter结构的用法
2016/07/07 Python
Python基于分水岭算法解决走迷宫游戏示例
2017/09/26 Python
对Python3中的input函数详解
2018/04/22 Python
python pycurl验证basic和digest认证的方法
2018/05/02 Python
Kears+Opencv实现简单人脸识别
2019/08/28 Python
Python中求对数方法总结
2020/03/10 Python
python3+selenium获取页面加载的所有静态资源文件链接操作
2020/05/04 Python
Harman Audio官方商店:购买JBL、Harman Kardon、Infinity和AKG
2019/12/05 全球购物
八一演出活动方案
2014/02/03 职场文书
小学生国旗下演讲稿
2014/04/25 职场文书
献爱心大型公益活动策划方案
2014/09/15 职场文书
运动会加油稿30字
2015/07/21 职场文书
《怀念母亲》教学反思
2016/02/19 职场文书
Python学习之异常中的finally使用详解
2022/03/16 Python
python图像处理 PIL Image操作实例
2022/04/09 Python