文档章节

python(六)切片,生成式,生成器,迭代

Koma
 Koma
发布于 2015/01/20 12:29
字数 2166
阅读 1976
收藏 11

有了前面的基础,其实掌握的比较扎实的话还是能够做出一些简单的东西的,至少解决一些个基本的数学题还是问题不大,比如说实现一个斐波那契数列,杨辉三角什么的。多数情况下使用循环 for ... in  或者  while 再加上 if 等就能够实现些很复杂的程序了。

接下来这部分内容的主要功能是为了简化循环而存在的,也秉持着python编程的一个原则:能一条代码解决的事儿决不写两条。就这样!

1,切片

切片,从字面上理解意思应该差不多能够到位。就是从一个大块儿中切出来一片或者一块儿。这个大块儿的东西,在程序中可以是列表,元组,集合,字典,字符串等。

举个例子,比如说从一个含有5个元素的列表中取出前三个元素,该怎么实现?

如果没学切片之前,可以用循环实现,就像这样:

但是如果使用python的切片操作,则很简单,就像是这样:

可以看到,python的切片操作符使用的是“[start:end]”,start 和 end 均表示元素的索引,获取到的元素在 [start, end) 之间,就是说包含 start 而不包含 end,如果你不指定 end 那么默认就切到结尾。

通过切片操作对列表,元组等数据结构进行操作之后返回的数据类型和原数据类型相同。

以上就是关于切片操作的基本介绍,当然,这也是它的全部。

那切片操作通常适用的场景就是,你希望可以快速的从一个列表或者什么中获取其中的一部分,那么用切片操作是最合适不过了!

当然了,切片操作还支持“倒着切”和对字符串进行切割。所谓的“倒着切”是因为,不管是列表还是元组,它们最后一个元素的索引在python中“规定为 -1”,那倒数第二个元素就是“-2”以此类推。

一个问题:切片可以对集合或者字典进行切割吗?解释一下原因。

2,生成式

生成式是另外一种操作。切片的目的是从过一个已有的列表中切出一部分返回,而生成式的目的则是从无到有的构建一个列表。

一个案例:假如我准备构建一个含有10个元素的列表,可以怎么做?

这里,可以利用python的一个内置函数xrange来生产一些数字,然后利用循环填充到一个列表中。

那么使用生成式应该怎么实现呢?我还是画(截)个图来看看:

效果一样,但是代码是不是少了很多。这就是python的编码原则,尽可能的少写代码!

同时呢,生成式还可以像for一样支持嵌套,当然了,不只是一级嵌套,同样也支持多级,不过通常情况下最多也只能用到二级了吧。以下的例子,使用生成式来生成两个字符串的全排列:

通过上面的两个例子,想必你已经看到了生成式的运行过程了吧?

对,就是你所想的那样,不要疑惑,记住它,在你以后的python路上这个会有很大的帮助!

注意:由于生成式只能采用“[]”这种方式,所以只能生产“list”类型的数据结构,所以生成式,通常情况下我们称之为:列表生成式。

补充:其实还可以生成集合,只需要把“[]”替换成“{}”

一个问题:上面的两句话矛盾吗?

3,生成器

如果你理解了生成式,那么对于生成器来说你只需要懂一点,那就是在生成式满足不了你的时候, 你可以考虑使用生成器。

所以生成器是生成式的加强版,注意:不是替代版!

一个案例:构建一个斐波那契数列数列的列表

方案一:采用循环的方式

由于在python中支持同时给多个变量赋值,所以代码可以简化成这样:

这里,简化之后的代码,最妙的一点我认为在于:在其它编程语言中,如果要做到两个变量的交换,那么一定需要引入中间变量,但是在python中利用“赋值符号 =”支持多赋值的机制可以很容易的避免这个问题。

上例中只是采用基本的python编程方法实现了我们的要求,但是这里能不能采用生成式来实现呢?

答案是可以的!

方案二:采用生成器

有些生成式的逻辑太过于复杂,导致我们没办法直接通过生成式来完成,这个时候可以借助于函数来完成复杂的逻辑,然后把函数转换成生成器,这样我们就可以“迭代”生成器来“模拟生成式”生成我们需要的列表。

那么在这里,把普通函数转换成生成器需要借助一个关键字“yield”。

它的作用是中断操作并返回,当下次再调用“next”方法的时候或者迭代的时候,从中断出继续执行,比如这样:

那现在,对于生成器,是不是有了一个大概的影响呢?

其实还一个问题,我说生成器是作为生成式的加强版,那么是不是应该生成式具有的功能,生成器同样应该具有呢?

就比如我们说生成式的时候的第一个案例,生成一个含有10个元素的列表,如果用生成器应该怎么实现?

可以看到,生成器和生成式,构建的方法的区别在于一个才用的是“[]”而一个采用的是“()”

同时对于生成器,如果你想构建一个列表,那么后期必须要通过“迭代”来实现,而生成式则可以直接实现。

同时,由于生成器的特殊性,导致如果你想访问生成器中的各个元素,则需要调用它的“next”方法。

以上就是对于生成器全部介绍。

经过仔细思考,对比之后,你就会有下面的一些总结:

对于生成式,它很局限,只能够帮助你快速的生成列表,而对于生成器,由于后期元素的访问必须要通过“迭代”,那么“迭代”出来的元素可以放到列表中,也可以放到集合、元组、字典中,所以采用生成器对于最终构建出来的数据类型没有限制。

那采用生成式还是生成器,这个就需要根据情况来自行决定了!

4,补充:迭代

什么叫迭代?说白了就是做循环,而且还是采用for ... in 这种循环结构。这就叫“迭代”!

上面这个,是我们经常用,也是一种最简单的迭代。

同样,我们也可以迭代字典:

默认情况下,迭代字典,迭代的是key,如果你想迭代value,你可以这样:采用 “itervalues”方法


当然,如果你想既迭代key也迭代value,那你可以这样:

然后,我们来看看 “iteritems”这个方法得到的数据类型:

看懂了这个类型,然后再看一个案例:

这样,你对迭代是不是就已经很清楚了呢?^_^

有了迭代的基础,再想想,我们的生成式和生成器,它们的内部不是也应用到了 for ... in 这种结构吗?于是下面这样子的代码你还看不懂吗?

O(∩_∩)O哈! 真是有趣,在python中,你可以尽情的把你的代码写的“高大上”一些,而且这也正是python所推荐你这么做的!

---------------------------------------------------华丽的分割线---------------------------------------------

切片,生成式,生成器,迭代,作为前面对python扩展数据结构的操作的一些补充说明,在今后的python编程中应用会非常频繁,所以一定要理解透彻,这样才能编写出“高大上”的代码嘛 ^_^



© 著作权归作者所有

共有 人打赏支持
Koma
粉丝 60
博文 144
码字总数 106280
作品 1
天津
程序员
私信 提问
python生成式生成器详细解答

Python得yield关键字,yield是python中的生成器 了解生成器需要先了解什么是生成式,切片的目的是从已有的列表中切出一部分返回,而生成式的目的则是从无到有的构建一个列表 一个生成式的案例...

开源中国段子手
2015/07/21
0
0
Python全栈工程师(迭代器、字节串)

ParisGabriel 每天坚持手写 一天一篇 决定坚持几年 为了梦想为了信仰                         Python人工智能从入门到精通 迭代器 Iterator:     用<>括号表示...

巴黎香榭
2018/07/20
0
0
python——高级特性(2)

迭代 在python中迭代是通过for ....in...完成的,只要是可迭代对象都可以迭代 #!usr/bin/python 008000;">-- coding:UTF-8 -- #tuple迭代t=[(1,'a','z'),(2,'b','z')]for x,y,z in t: #enume......

乌云上
2018/05/04
0
0
基于编程人员Python学习第一章节

基于廖雪峰的python零基础学习后,自我总结。适用于有一定基础的编程人员,对我而言,则是基于.net已有方面,通过学习,记录自我觉得有用的地方,便于后续回顾。 主要以快速定位内容,通过直...

Aikenwu
2018/08/13
0
0
Python系列(三)之Python高级特性

1. 切片 切片操作(slice),即从list(tuple是一种特殊的list)中获取部分元素。 L[m,n]表示从L[m]~L[n-1]的list。 L[:n]表示从L[0]~L[n-1]的list。 L[m:]表示从L[m]~L[len(L)-1]。 L[-m:]...

huwh_
2017/12/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

PHP is_numeric 检测变量是否为数字或数字字符串

bool is_numeric ( mixed $var ) 如果 var 是数字和数字字符串则返回 TRUE,否则返回 FALSE。 For example 1: <?php $v = is_numeric ('58635272821786587286382824657568871098287278......

james_laughing
8分钟前
1
0
聊聊flink的NetworkEnvironmentConfiguration

序 本文主要研究一下flink的NetworkEnvironmentConfiguration NetworkEnvironmentConfiguration flink-1.7.2/flink-runtime/src/main/java/org/apache/flink/runtime/taskmanager/NetworkEnv......

go4it
今天
4
0
极路由4刷OpenWrt(LEDE)

申请开发者模式 登录路由器后台 进入插件中间 选中路由器信息 申请开发者权限 安装开发者插件 刷 Bootloader 下载 极路由4 的 Breed 通过SSH登录路由器 (必须安装开发者插件,端口 1022 账号...

dingdayu
今天
3
0
浅淡个人学习嵌入式Linux过程

我专业是电子信息工程,在初入大学的时候,我们的班主任便要我们多多去了解一些关于电子方面的知识。后来我了解到了嵌入式,继而了解到了嵌入式Linux。其实我们学习linux差不多就学习linux内...

linux-tao
今天
7
0
SpringBoot使用GraphQL简单学习-1

官网 一、GraphQL简介 1.GraphQL是什么? GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够...

wind2012
今天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部