python高级特性:切片/迭代/列表生成式/生成器
廖雪峰老师的教程上学来的,地址:python高级特性
下面以几个具体示例演示用法:
一、切片
1.1 利用切片实现trim
def trim(s): while s[:1] == " " or s[-1:] == " ": # 若第1个元素或最后1个元素为空格 if s[:1] == " ": s = s[1:] if s[-1:] == " ": s = s[:-1] return s
注:字符串可以看做一个list,列表切片的完整写法是 L[start:end],其中end也支持负数,最后一个数用-1表示,第1个数用0表示,如果省略start,表示从0开始,如果省略end,表示到最后1个元素结束。
测试代码:
if trim('hello ') != 'hello': print('测试失败1!') elif trim(' hello') != 'hello': print('测试失败2!') elif trim(' hello ') != 'hello': print('测试失败3!') elif trim(' hello world ') != 'hello world': print('测试失败4!') elif trim('') != '': print('测试失败5!') elif trim(' ') != '': print('测试失败6!') else: print('测试成功!')
1.2 切片还有第3个参数,即:L[start:end:skip],比如在1-10之间,把奇数、偶数选出来
list_1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] odd = list_1[::2] even = list_1[1::2] print(odd) print(even)
输出:
[1, 3, 5, 7, 9]
[2, 4, 6, 8, 10]
二、迭代
list_1 = list(range(1, 11)) print("正向迭代:") for x in list_1: print(x) print("\n反向迭代:") for x in reversed(list_1): print(x) print('\n带索引的迭代:') for m in enumerate(list_1): print("list_1[", m[0], "]=", m[1]) dic_1 = {"name": "菩提树下的杨过", "blog": "http://yjmyzz.cnblogs.com/"} # 字典的迭代 print("\ndict字典迭代1:") for k in dic_1: print("key:", k, ",value:", dic_1[k]) print("\ndict字典迭代2:") for v in dic_1.values(): print("value:", v) print('\ndict字典迭代3:') for k, v in dic_1.items(): print("key:", k, ",value:", v)
输出:
正向迭代: 1 2 3 4 5 6 7 8 9 10 反向迭代: 10 9 8 7 6 5 4 3 2 1 带索引的迭代: list_1[ 0 ]= 1 list_1[ 1 ]= 2 list_1[ 2 ]= 3 list_1[ 3 ]= 4 list_1[ 4 ]= 5 list_1[ 5 ]= 6 list_1[ 6 ]= 7 list_1[ 7 ]= 8 list_1[ 8 ]= 9 list_1[ 9 ]= 10 dict字典迭代1: key: name ,value: 菩提树下的杨过 key: blog ,value: http://yjmyzz.cnblogs.com/ dict字典迭代2: value: 菩提树下的杨过 value: http://yjmyzz.cnblogs.com/ dict字典迭代3: key: name ,value: 菩提树下的杨过 key: blog ,value: http://yjmyzz.cnblogs.com/
三、列表生成器
这个老厉害了!比如:要找出1~100内所有奇数的平方数(即:1,3,5... 这些数的平方数)
a = [x ** 2 for x in range(1, 101) if x % 2 == 1 and x ** 2 <= 100] print(a)
输出:[1, 9, 25, 49, 81]
再比如,打印出当前目录下的所有文件(不考虑递归子目录)
import os print([f for f in os.listdir(".")])
小结:写法就是 [... for ... in .. if ...] ,要生成的list项写在for前面,如果迭代时需要指定条件,写在最后的if中。
四、生成器(generator)
这是python引入的一个新概念,想想刚才学到的列表生成器:
result1 = [x ** 2 for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]] print(type(result1), result1)
输出:
<class 'list'> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
不知道大家想过没有:如果for前面的运算比较复杂(比如:求平方根),而for迭代的列表又很大(比如:1千万个),最终列表生成器肯定运行很慢,会严重影响性能。能不能做到『延时』计算?等到真正要用的时候,再按需计算。这就是生成器(generator)要解决的问题,它与[列表生成器]的区别在于,它只保存计算逻辑(即: 保存算法),并不马上计算结果,真正要用的时候,调用next(g)取出下一个计算结果即可,当然,它也支持迭代。
generator1 = (x ** 2 for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) print(type(generator1), generator1) # 取出第1个值 print(next(generator1)) # 取出第2个值 print(next(generator1)) # 打印剩余的值 for x in generator1: print(x)
输出:
<class 'generator'> <generator object <genexpr> at 0x1087e7f10> 1 4 9 16 25 36 49 64 81 100
从输出类型上看,它的类型是generator,而非list。单纯从语法上看,只要把"列表生成器"的[],换成()即可。
再来一个复杂点的示例,中学我们都学过"杨辉三角",如果用常规思路,打印出杨辉三角,可以参考下面的代码:
import copy def triangles(limit): first, second = [1], [1, 1] print(first) if limit > 1: print(second) if limit == 2: return x = copy.copy(second) while True: y = copy.copy(first) [y.append(x[i] + x[i + 1]) for i in range(len(x) - 1)] y.append(1) print(y) x = copy.copy(y) if len(y) >= limit: return triangles(10)
输出:
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
如果,要改写成生成器(generator),该怎么做呢?答案:只要把print(...)的地方,改成yield 即可。
def triangles_generator(limit): first, second = [1], [1, 1] yield first if limit > 1: yield second if limit == 2: return x = copy.copy(second) while True: y = copy.copy(first) [y.append(x[i] + x[i + 1]) for i in range(len(x) - 1)] y.append(1) yield y x = copy.copy(y) if len(y) >= limit: return g = triangles_generator(10) # 取出前2个 print(next(g)) print(next(g)) # 剩下的用迭代写法输出 for x in g: print(x)
输出与刚才相同,就不重复贴了。关于这个yield,如果还没理解的,可以对比看下面的示例:
def test1(): return [1, 2, 3] def test2(): print("test2=>1") yield 1 print("test2=>2") yield 2 print("test2=>3") yield 3 print(test1()) g = test2() print(next(g)) print(next(g)) print(next(g))
输出:
[1, 2, 3]
test2=>1
1
test2=>2
2
test2=>3
3
test2()遇到yield后,会停下来,保存现场,等待下一次调用next()时,才会继续执行。
出处: http://yjmyzz.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
MODIS数据的简介和下载(四)——HTTPS服务下载说明
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ESA_DSQ/article/details/80042711 由于NASA官方MODIS服务的变化和网站的改版。所以重新来介绍下MODIS数据新的下载方式。至于数据的简介和Web Service的,不清楚的小伙伴可以去点击前面的文章回顾下(其中“MODIS数据的简介和下载(二)”一文教程由于NASA官网关闭FTP服务器的原因在最后提交数据的部分有所变化,详情见本文)。 MODIS数据的简介和下载(一)——MODIS数据简介 MODIS数据的简介和下载(二)——MODIS数据下载方式(FTP) MODIS数据的简介和下载(三)——MODIS数据下载方式(基于MODIS Web Service) MODIS数据的简介和下载(番外篇)——MODIS Web Service的Python客户端应用 注册了NASA官网earthdata账户的小伙伴们应该在最近都收到了NASA官网关于关闭FTP服务器的邮件,之前也有评论区的小伙伴来询问相关。今天就来介绍新的下载方式。 1 NASA官方邮件通知 2...
- 下一篇
Effective C++学习笔记
导读 本书的最佳用途:彻底了解C++如何行为,为什么那样行为,以及如何运用其行为形成优势。 size_t是一个typedef,是某种不带正负号的unsigned类型。 签名(signature):函数的参数和返回值。即std::size_t num(int number) 的签名是 std::size_t ( int ) explicit可组织他被用来隐式转换(implicit type conversions),但他仍可以被进行显示转换(explicit type conversions)。 如图: 拷贝构造---以同型对象初始化自我对象。 拷贝赋值---从另一个同性对象中拷贝其值到自我对象。 1、让自己习惯C++ 条款一:视C++为一个语言联邦 c++是四种语言的联邦 每种语言都有自己的规约。C++高效编程守则视状况而变化,取决于你使用C++的哪一部分。 条款2:尽量以const、enum、inline替换#define 也就是“宁可以编译器替换预处理”。因为define或许不被视为语言的一部分。 class专属常量:为了将常量的作用域(scope)限制于class内,必须让它成为...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
-
Docker使用Oracle官方镜像安装(12C,18C,19C)
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
推荐阅读
最新文章
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- Docker安装Oracle12C,快速搭建Oracle学习环境