day18-列表生成式、迭代器
1、列表生成式,也叫列表推导式
即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
优点:构造简单,一行完成
缺点:不能排错,不能构建复杂的数据结构
1.1、循环模式[i for i in iterable]
l1 = [i for i in range(1,101)]
print(l1)
l2 = ['python第%s天'%i for i in range(1,11)]
print(l3)
结果:
['python第1天', 'python第2天', 'python第3天', 'python第4天', 'python第5天', 'python第6天', 'python第7天', 'python第8天', 'python第9天', 'python第10天']
10以内的数的平方
l3 = [i*i for i in range(11)]
print(l3)
结果:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
1.2、筛选模式[i for i in iterable if 判断式]
a = [i for i in range(1,100) if i%2==1]
print(list(a))或print(a)
结果:
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97, 99]
或一句话输出
print([i for i in range(1,100) if i%2==0])
结果:
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98]
30以内能被3整除的数的平方
l4 = [i*i for i in range(31) if i%3 == 0]
print(l4)
结果:
[0, 9, 36, 81, 144, 225, 324, 441, 576, 729, 900]#
过滤掉非字符串类型和长度小于3的字符串,并将剩下的转成大写字母
lst = ['mike', 'tom', 'jack', 're', 'ab', 123]
l5 = [i.upper() for i in lst if isinstance(i, str) and len(i) >= 3]
print(l5)
结果:
['MIKE', 'TOM', 'JACK']
列出当前目录下的所有文件和目录名,可以通过一行代码实现:
import os
print([d for d in os.listdir('.')]) # os.listdir可以列出文件和目录
['.emacs.d', '.ssh', '.Trash', 'Adlm', 'Applications', 'Desktop', 'Documents', 'Downloads', 'Library', 'Movies', 'Music', 'Pictures', 'Public', 'VirtualBox VMs', 'Workspace', 'XCode']
3、两层循环,可以生成全排列
print([m + n for m in 'ABC' for n in 'XYZ'])
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
列表生成式也可以使用两个变量来生成list:
d = {'x': 'A', 'y': 'B', 'z': 'C' }
print([k + '=' + v for k, v in d.items()])
['y=B', 'x=A', 'z=C']
一句话生成九九乘法表
print ('\n'.join([' '.join(['%s*%s=%-3s'%(y,x,x*y) for y in range(1,x+1)]) for x in range(1,10)]))
2、迭代器
1、可迭代对象
内部含有'__iter__'方法的数据就是可迭代对象
可迭代对象:list、str、tuple、set、dict、range()、文件句柄
print(dir(对象名))
如果打印结果里面有'__iter__',则这个对象就是可迭代对象
print('__iter__' in dir([1,2,3]))
True
如果结果为True,就表示对象是可迭代对象
2、迭代器
内部含有'__iter__'方法,并且含有'__next__'方法的对象就是迭代器
文件句柄就是一个迭代器
f1 = open('1.txt', encoding='utf-8'):
print('__iter__' in dir(f1))
True
print('__next__' in dir(f1))
True
l1 = [1,2,3,'a']
iter1 = iter(l1)
或
iter1 = l1.__iter__() print(iter1.__next__())
print(iter1.__next__())
print(iter1.__next__())
print(iter1.__next__()) 1
2
3
a
#迭代完了之后如果再取值,就会报错StopIteration
迭代器特点:
1、非常节省内存
2、满足惰性机制
3、一条路走到黑
利用while循环模拟for循环
1、将可迭代对象转化成迭代器
2、利用next进行取值
3、利用异常处理终止循环
l1 = [1,2,3,'a']
iter1 = l1.__iter__()
while 1:
try:
print(iter1.__next__())
except StopIteration:
break
3、生成器,自己用python代码写的迭代器
通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。
所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。
有两种方式:
1、函数式写法
2、生成器表达式
函数式写法,构建生成器
只要函数中出现yield,那么他就不是一个函数了,他是生成器函数
def func1():
yield 3
yield 4
func1() #这样不会调用该函数 g = func1()
print(g.__next__()) #一个next对应一个yield的值
print(g.__next__()) #再一个next对应下一个yield的值 3
4
yield和return的区别
return 结束函数,给函数返回值
yield不会结束生成器函数,一个next对应一个yield进行取值
例子:如果循环打印一个列表,可以同时打印出来
def num1():
for i in range(1,11):
print('编号%s'%(i))
num1() 编号1
编号2
编号3
编号4
编号5
编号6
编号7
编号8
编号9
编号10
也可以不一次性打印出来,需要打印几个就先打印出几个
def num2():
for i in range(1,11):
yield ('编号%s'%(i))
g = num2() #这里需要将函数执行重新赋值给一个变量,不能用print(num2().__next__(),否则每次打印都是第一个值1
print(g.__next__())
#编号1
for i in range(3):
print(g.__next__())
#编号2
#编号3
#编号4
for i in range(6):
print(g.__next__())
#编号5
#编号6
#编号7
#编号8
#编号9
#编号10
4、生成器表达式
只需要将列表推导式用小括号表示即可生成一个生成器迭代器
g1 = (i*i for i in range(10000))
print(g1.__next__())
print(g1.__next__())
print(g1.__next__())
print(g1.__next__())
print(g1.__next__())
0
1
4
9
如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。
比如,著名的斐波拉契数列(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+=1 fib(6)
1
1
2
3
5
8
13
仔细观察,可以看出,fib函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。
也就是说,上面的函数和generator仅一步之遥。要把fib函数变成generator,只需要把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
print('done')
g = fib(6)
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
print(g.__next__())
1
1
2
3
5
把函数改成generator后,如果用next()来获取下一个返回值有点麻烦,也可以直接使用for循环来迭代:
for n in fib(6):
print(n)
1
1
2
3
5
8
例子:
杨辉三角定义如下:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
把每一行看做一个list,试写一个generator,不断输出下一行的list:
def triangel(max):
n,L=0,[1] #定义一个list[1]
while n<max:
yield L #打印出该list
L=[1]+[L[x]+L[x+1] for x in range(len(L)-1)]+L[1] #计算下一行中间的值,两边再各添加一个[1] #生成一个generator对象,然后通过for循环迭代输出每一行
a=triangel(10)
for i in a:
print(i)
或者
def triangles(max):
L=[1]
i = 0
while n<max:
yield L
L.append(0)
L = [L[i-1]+L[i] for i in range(len(L))] a=triangel(10)
for i in a:
print(i)
注:普通函数和generator生成器的区别:
1.普通函数调用直接返回结果,generator函数的调用,返回一个generator对象;
(调用generator时可以先创建一个对象,再用next()方法不断获得下一个返回值,但实际中通常用for循环实现)
2.generator在执行过程中,遇到yield就中断,下次又继续执行
day18-列表生成式、迭代器的更多相关文章
- Day4- Python基础4 深浅拷贝、三目运算、列表生成式,迭代器&生成器、装饰器
本节内容: 1.深浅拷贝 2.三目运算 3.迭代器和生成器 4.装饰器 1.深浅拷贝 拷贝意味着对数据重新复制一份,深浅拷贝的含义就是:对于修改复制的数据是否会影响到源数据,拷贝操作对于基本数据结构需 ...
- python迭代器和生成器(3元运算,列表生成式,生成器表达式,生成器函数)
1.1迭代器 什么是迭代器: 迭代器是一个可以记住遍历的位置对象 迭代器对象从集合的第一个元素元素开始访问,直到所有元素被访问完结束,迭代器只能往前不会后退. 迭代器有两个基本方法:iter ,nex ...
- Python 列表生成式、生成器、迭代器
列表生成式 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式. 如果要生成[1x1, 2x2, 3x3, ..., 10x10]怎么 ...
- Python之列表生成式、生成器、可迭代对象与迭代器
本节内容 语法糖的概念 列表生成式 生成器(Generator) 可迭代对象(Iterable) 迭代器(Iterator) Iterable.Iterator与Generator之间的关系 一.语法 ...
- 简学Python第四章__装饰器、迭代器、列表生成式
Python第四章__装饰器.迭代器 欢迎加入Linux_Python学习群 群号:478616847 目录: 列表生成式 生成器 迭代器 单层装饰器(无参) 多层装饰器(有参) 冒泡算法 代码开发 ...
- Day4 函数、列表生成式、生成器、迭代器
温故而知新: 1. 集合 主要作用: 去重 关系测试, 交集\差集\并集\反向(对称)差集 2. 元组 只读列表,只有count, index 2 个方法 作用:如果一些数据不想被人修改, 可以存成元 ...
- 列表生成式、生成器&迭代器
一.列表生成式 先有列表[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],要求你把列表里的每个值加1,怎么实现? 方法一: a = [0, 1, 2, 3, 4, 5, 6, 7, 8, ...
- 列表生成式,迭代器&生成器
python3中range(10)就 是迭代器 列表生成式 #列表生成式 a=[0,1,2,3,4,5] b=[] for index,i in enumerate(a): a[index]+1 pr ...
- Python —— 函数高级特性(切片、迭代、列表生成式、生成器、迭代器)
一.切片(Slice) 在很多编程语言中,针对字符串提供了很多截取函数(i.e. substring),目的就是对字符串切片.python中没有针对字符串的截取函数,需要通过“切片”来完成. 取一个 ...
- python 列表生成式,生成器&迭代器
列表生成式: 需求:要对列表 [0,1,2,3,4,5,6,7,8,9]的每个元素加1 用列表生成式一步搞定: li = [i+1 for i in range(10)] # 这种写法就叫列表生成式 ...
随机推荐
- 使用Apache Mesos和Consul实现服务的注册发现
为保证基于Docker应用程序和服务都具有高性能和可用性,设计出一种具有服务发现,高可用性和容错能力的解决方案非常重要. 我们使用Apache Mesos 和Mesosphere的 Marathon实 ...
- Python——字符串(python programming)
p ython——字符串 ①加法 连接两个字符串 ②乘法 复制字符串 python——转义字符 \n 换行 \' 单引号 \'' 双引号 \\ 反斜杠 raw字符串:无视转义字符 转义: 字符串 ...
- Java-Runoob-高级教程-实例-方法:02. Java 实例 – 输出数组元素
ylbtech-Java-Runoob-高级教程-实例-方法:02. Java 实例 – 输出数组元素 1.返回顶部 1. Java 实例 - 输出数组元素 Java 实例 以下实例演示了如何通过重 ...
- Uc的个人中心很奇葩
Uc的个人中心很奇葩,未登录前点击头像是图2选择性别,点击云同步才是图3登录,登录之后,想退出,要点击图1的头像进入图4编辑资料,然后右上角退出登录…摸索了好久,差点抓狂…把你们的产品经理叫出来一下… ...
- Ubuntu14.04 下软件安装和卸载命令备记
一.Ubuntu中软件安装方法 1.APT方式 ()普通安装:apt-get install softname1 softname2 …; ()修复安装:apt-get -f install soft ...
- Kowala协议:一组分布式,自我调节,资产跟踪特性的加密货币(二)
对于稳定币来言,设计过程中会遇到很多细节的问题,今天来讲述下有关通证设计过程中的一些问题. 1.计算手续费 计算费是交易费的一部分,转移给kUSD矿工,并由以下公式决定: 其gasUsed(t) 是用 ...
- Java 11 - Java String类
Java String类 字符串广泛应用在Java编程中,在Java中字符串属于对象,Java提供了String类来创建和操作字符串. 创建字符串 创建字符串最简单的方式如下: String gree ...
- CCProxy
我在之前的博客里提到了用Teamviewer + CCProxy做内网穿透,当时只是简单提了一下,因为发现这种方式网速比较慢.今天又用到了它,虽然慢点,但是总比没的用好,哈哈哈.不得不感叹CCProx ...
- 在mvc中动态加载菜单
最近做了一个项目, 要在客户端动态的显示菜单,也就是这些菜单是保存在数据库中的, 在客户端动态加载菜单,这样做的好处很明显,就是菜单很容易修改,直接在后台进行维护,再也不会直接在前面的 视图页面中进行 ...
- mocha测试接口类型及测试报告收集
记录参考: 参考文档: 测试报告以及es6: http://www.ruanyifeng.com/blog/2015/12/a-mocha-tutorial-of-examples.html 测试接口 ...