3800 字 Python 流程控制专题总结
toyiye 2024-09-12 20:57 3 浏览 0 评论
流程控制与代码的执行顺序息息相关,流程控制相关的关键字,如if
,elif
,for
,while
,break
,continue
,else
,return
,yield
,pass
等。
本专题详细总结与流程控制相关的基础和进阶用法,大纲如下:
基础用法
1 if 用法
2 for 用法
3 while,break,continue
进阶用法
4 for 使用注意
5 range 序列
6 Python特色:循环与else
7 pass 与接口
8 return 和 yield
9 短路原则
总结
基础用法
专题的开始,先总结与流程控制相关的基础用法。
1 if 用法
if
对应逻辑控制的条件语句,它的基本结构可以表示为:如果满足某个条件,则怎么怎么样。
如下函数maxChunksToSort
中,如果满足当前数组nums
的索引i
等于区间[0,i]
的最大值,则[0,i]
区间能被分割为一个Chunk.
def maxChunksToSort(nums):
maxn, count = nums[0], 0
for i,num in enumerate(nums):
maxn = max(maxn, num)
if i == maxn:
count += 1
return count
if
后的语句指定了一个条件,若满足if
则,:
后的语句成立。
如果if
不满足,再使用elif
判断其他情况,可以一直写elif
,若是最后一个判断条件,可使用else
,其基本结构为:
if A:
print('condition A meets')
elif B:
print('condition B meets')
elif C:
print('condition C meets')
else:
print('other conditions meets')
2 for 用法
Python的for
除了具备控制循环次数外,还能直接迭代容器中的元素。
控制循环次数:
for i in range(1, len(nums)):
print(i)
还能直接操作容器内的元素:
a = [1, [2, 4], [5, 7]]
for item in a:
print(item)
3 while,break,continue
while
后面紧跟一个判断条件,若满足条件则会一直循环,直到不满足条件时退出。但这不是绝对的,如果while后的语句块内含有break
,即便条件依然满足,但遇到break
也会一样退出。
如下检测输入是否为整数,直到输入整数时,执行break
退出while
循环:
while True:
a = input('please input an Integer: ')
try:
ai = int(a)
print('输入了一个整数 %d ,input 结束' % (ai,))
break
except:
print("%s isn't a Integer" % (a,))
做如下测试:
please input an Integer: 1.2
1.2 isn't a Integer
please input an Integer: 1
输入了一个整数 1 ,input 结束
continue
与最近的循环语句for
或while
组合,表示接下来循环体内的语句不执行,重新进入下一次遍历。
def f(nums):
for num in nums:
if num <= 0:
continue
print('得到一个大于0的数 %d' % (num,))
做如下测试:
得到一个大于0的数 2
得到一个大于0的数 4
进阶用法
基础用法保证我们能够应付日常遇到的基本的代码流程,不过要想进一步深入理解Python特色的、与顺序相关的执行功能,还需要理解下面的进阶用法。
4 for 使用注意
for 语句遍历容器类型或可迭代类型时,如果涉及到增加、删除元素,就需要小心。比如请先看下面的例子:
删除列表中的某个元素值,可能有重复,要求元素顺序不变,空间复杂度为O(1),如果像下面这样写就会有问题:
def delItems(nums, target):
for item in nums:
if item == target:
nums.remove(item)
return nums
对于大多数情况,上面的代码无法暴露出bug。但是考虑下面输入(特点:被删除的值连续出现):
r = delItems([2, 1, 3, 1, 1, 3], 1)
print(r)
打印结果为:[2,3,1,3]
对于刚接触编程的朋友对此很不解,为什么其中一个1
未被remove.
不管是Python, Java, C++,列表或数组删除元素时,其后面的元素都会逐次前移1位,但是for
依然会正常迭代,因此“成功”规避了相邻的后面元素1.
图形解释命中目标后的一系列动作:
下步最关键:解释器自动前移删除位置后的所有元素
但是,等到下一次迭代时,迭代器不等待,正常移动到下一个位置:
这样元素3
成功逃避是否与目标值相等的检查。
结论:命中目标处的后一个位置都逃避了是否与目标值相等的检查,所以一旦有连续目标值,必然就会漏掉,进而触发上面的bug.
明白上面这个原因后,重新再改写一遍删除所有重复元素的代码,下面代码不再使用for
直接遍历元素(再说一遍:增删元素原来迭代器发生改变,所以会导致异常行为),而是使用索引访问:
def delItems(nums, target):
i = 0
while i < len(nums):
if nums[i] == target:
del nums[i]
i -= 1
i += 1
return nums
r = delItems([2, 1, 3, 1, 1, 3], 1)
print(r) # [2,3,3]
如果元素等于target
,从数组nums
中删除nums[i]
,删除后解释器自动将i
后的元素都前移1位。据此,巧妙的控制i
值,一旦命中立即i
减去1,这样确保不漏检查。
5 range 序列
range
在Python中经常用于生成一串数字序列,对刚入门Python的朋友想尝试打印其中的值:
In [3]: print(range(10))
range(0, 10)
要想看到每个值可与for
结合:
In [21]: for i in range(10):
...: print(i,end=",")
...:
0,1,2,3,4,5,6,7,8,9,
那么有的朋友不禁要问range
函数的返回值为什么能与for
结合?
类型为Iterable
的对象都可与for
结合,下面确认range(10)
返回值是否为Iterable
:
In [13]: from collections.abc import Iterable
In [14]: isinstance(range(10),Iterable)
Out[14]: True # 它是 Iterable 类型
它为什么不是一次全部输出一个列表,就像下面这样:
In [23]: list(range(10))
Out[23]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
而是要一个一个的输出?
range
函数为了高效节省内存,一次只返回一个值,而不是直接将构成序列的全部元素加载到内存。
Python里的range不支持创建浮点序列,所以为了更加清楚的展示range
的原理,编写一个创建浮点数的序列frange
:
def frange(start, stop, step):
i = start
while i < stop:
yield i
i += step
代码只有几行,yield
作为控制流程的一个关键字,下面我们会详细说到。
使用frange
:
fr = frange(0, 1.,0.2)
for i in fr:
print("{:.2f}".format(i),end=",")
打印结果如下,得到一个差值为0.2
的等差数列:
0.00,0.20,0.40,0.60,0.80,
6 Python特色:循环与else
6.1 for
能和else
组对
Python一大特色:while
,for
能和else
组对,不仅如此,try
except
和else
也能组对,下面介绍它们存在的价值。
找出2到15的所有素数,如果不是素数打印出一对因子,实现代码如下:
for num in range(2, 16):
is_prime = True
for item in range(2, num):
if num % item == 0:
print('%d = %d*%d ' % (num, item, num // item))
is_prime = False
break
if is_prime:
print("%d is prime" % (num))
打印结果如下:
2 is prime
3 is prime
4 = 2*2
5 is prime
6 = 2*3
7 is prime
8 = 2*4
9 = 3*3
10 = 2*5
11 is prime
12 = 2*6
13 is prime
14 = 2*7
15 = 3*5
使用is_prime
标志位判断是否找到num
的一对因子,若都遍历完仍无发现则打印此数是素数。
这是我们比较熟悉的常规解决思路,但是如果使用for
和else
组对,它的价值便能体现出来:
for num in range(2, 16):
for item in range(2, num):
if num % item == 0:
print('%d = %d*%d ' % (num, item, num // item))
break
else:
print("%d is prime" % (num))
上面代码实现同样的功能,但代码相对更加简洁。通过前后代码对比,我们便能看出for
和else
组对的功能:for
遍历完成后执行else
,但是触发break
后,else
不执行。
大家平时多多使用,便能习惯以上用法。通过上面的对比,我们也能直观的感受到它们的价值。
6.2 try
,except
和else
组对
try 和 except 组对比较容易理解,触发异常执行 except 里的代码,否则不执行。
但是加上一个else
实现怎样的作用呢?
首先看下面的例子:
In [9]: while True:
...: try:
...: a = int(input('请输入一个整数: '))
...: except ValueError:
...: print('input value is not a valid number')
...: else:
...: if a % 2 == 0:
...: print('输入的 %d 是偶数' %(a,))
...: else:
...: print('输入的 %d 是奇数' %(a,))
...: break
测试:
请输入一个整数: t
input value is not a valid number
请输入一个整数: 5
输入的 5 是奇数
try 保护的代码正常通过后,else
才执行。
有的朋友会问,为什么不把else
这块代码放到try
里面?这还是有一定区别的:放到else
中意味着这块代码不必受保护,因为它不可能触发ValueError
这样的异常。
7 pass 与接口
Python中最特别的关键字之一便是pass
,它放在类或函数里,表示类和函数暂不定义。
class PassClass:
pass
def PassFun:
pass
如上实现最精简的类和函数定义。
今天跟大家分享一个pass
的特别有用的用法,尤其对Java
语言的interface
,implements
等较熟悉的朋友,在Python中也能实现类似写法。
首先安装一个包:
pip install python-interface
下面是这个包的基本用法,首先创建一个接口类:
from interface import implements, Interface
class MyInterface(Interface):
def method1(self, x):
pass
def method2(self, x, y):
pass
下面实现接口:
class MyClass(implements(MyInterface)):
def method1(self, x):
return x * 2
def method2(self, x, y):
return x + y
这个包对熟悉Java
语言的朋友还是非常实用,接口和实现类用法,可以平稳过渡到Python
语言中。
8 return 和 yield
程序遇到 return
和yield
都是立即中断返回。那么yield
和return
又有什么不同呢?
与return
不同,yield
中断返回后,下一次迭代会进入到yield后面的下一行代码,而不像return下一次执行还是从函数体的第一句开始执行。
用图解释一下:
第一次 yield 返回 1
第二次迭代,直接到位置2这句代码。
然后再走for
,再yield
,重复下去,直到for
结束。
以上就是理解yield
的重要一个点,当然yield
还会与from
连用,还能与send
实现协程等,这些都放在后面的专题。
9 短路原则
最后以一个有意思的短路问题结束流程控制专题。
布尔运算符 and
和or
也被称为短路运算符:它们的参数从左至右解析,一旦可以确定结果解析就会停止。
Python中的短路运算符常见的有两个:and
,or
A and B : 如果 A 不成立,B 不会执行
A or B : 如过 A 成立,B不会执行
所以被称为短路运算符
举几个例子一看就明白,请看下面代码:
代码1:
a = ''
b = a and 'i will not execute'
print(b)
打印结果为空,因为and
运算符从左到右检查,一旦a
为空即为假,则结果已确定为假,'i will not execute'
被短路。
代码2:
a = 'python'
b = a or 'i will not execute'
print(b)
打印结果为:python
,因为or
运算符从左到右检查,一旦a
为真则结果已确定为真,所以'i will not execute'
被短路。
总结
本专题细致总结了流程控制的基础和进阶用法,具体包括以下:
基础用法
1 if 用法
2 for 用法
3 while,break,continue
进阶用法
4 for 使用注意
5 range 序列
6 Python特色:循环与else
7 pass 与接口
8 return 和 yield
9 短路原则
总结
《end》
Python学习交流群
为了让大家更加即时地沟通学习,我们建了一个Python学习交流群,有想入群的同学,可以添加下面小助手微信,他会拉大家入群哈~
相关推荐
- 为何越来越多的编程语言使用JSON(为什么编程)
-
JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...
- 何时在数据库中使用 JSON(数据库用json格式存储)
-
在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...
- MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)
-
前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...
- JSON对象花样进阶(json格式对象)
-
一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...
- 深入理解 JSON 和 Form-data(json和formdata提交区别)
-
在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...
- JSON 语法(json 语法 priority)
-
JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...
- JSON语法详解(json的语法规则)
-
JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...
- MySQL JSON数据类型操作(mysql的json)
-
概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...
- JSON的数据模式(json数据格式示例)
-
像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...
- 前端学习——JSON格式详解(后端json格式)
-
JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...
- 什么是 JSON:详解 JSON 及其优势(什么叫json)
-
现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...
- PostgreSQL JSON 类型:处理结构化数据
-
PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...
- JavaScript:JSON、三种包装类(javascript 包)
-
JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...
- Python数据分析 只要1分钟 教你玩转JSON 全程干货
-
Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...
- 比较一下JSON与XML两种数据格式?(json和xml哪个好)
-
JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- r语言矩阵 (127)
- browsererror (114)
- exportexcel (119)
- cv2.bitwise_not (137)
- dump命令 (128)
- es6concat (126)
- heapify (127)
- java.security.egd (130)
- javax.annotation (117)
- jsstringsplit (117)
- js数字 (115)
- maven编译 (132)
- mysqlleft (128)
- nodejsbuffer (149)
- org.apache.commons.httpclient (126)
- org.jsoup (141)
- org.springframework.web (128)
- robotframework-ride (115)
- setnocounton (141)
- socket.gethostbyname (122)
- sqlmid (121)
- time.strptime (133)
- vscode格式化 (125)
- win32con (129)
- window.localstorage (126)