Python笔记_第一篇_面向过程第一部分_6.循环控制语句(while 和 for)_

时间:2023-02-13 22:22:45

  承接条件控制语句。条件控制语句像大树一样有很多的之差,那条路径通(也就是表达式判断为True)就会往哪一个树杈去运行,万涓溪水汇成大河。对于常用的程序结构形式,还有一种这篇文章就会讲解,那就是循环控制语句。正如前面所说,程序的执行是由上而下,从左至右的运行方式,但是如果我们遇到一件事情:需要做的事情都相似,只是需要重复做很多遍,如果只有条件控制语句,一个小细节就要执行一遍,那就太蛋疼了,因此除了在实际工作中遇到像大树一样逻辑的思路,我们需要让程序这种由上而下,从左只有的运行过程中,执行到我们想要重复做很多遍的事情,让这种法则局部“失效”。来回去运行计算,然后运行计算完毕后,继续按照这种运行法则向下去执行,答案是肯定的:那就是循环语句。

  循环控制语句简介

  我们把循环控制语句比作一个圆圈,符合一个条件就循环一次,符合一个条件就循环一次。和条件控制语句一样,其循环控制语句也有一个原则,这个原则叫避免死循环

  死循环:

  也就是说,在一个循环体内,由于设置的表达语句一致符合某个条件,这样就跳不出这个圆圈而在里面一致执行(如果电脑不死机,一直执行到海枯石烂!)。所以切记在循环控制语句内一定要避免死循环的发生。

  循环控制语句在python中有两种形式一种叫while循环控制语句,另外一种叫for循环控制语句。while看起来逻辑上比较繁琐,但是不能这样说,各自在解决某些问题上,都有相对好的选择。

第一部分: while 循环控制语句

  存在形式如下:

  (1)  num = 0   # 计数器初始化

    while num <=/< 表达式

      循环内容

      num += 1  # 计数器运行部分# while循环语句要加一个计数器

  (1)  num = 0   # 计数器初始化

    while num <=/< 表达式:

      循环内容

      num += 1  # 计数器运行部分

    else:  # 循环结束时执行这个位置

      语句

  解释如下

  其实这两种形式的区别就是后面增加了一个else:也就说形式(2) 整个循环体结束完毕后,再执行一个else:语句的内容。直白点儿说就是:“循环计算完毕,你还有什么话要说”?

  因此,单独解释一下形式(1)即可:

  计数器起到的作用就给定计数器一个初始值(这个变量名随便)随着表达式的内容一直为真,循环一直执行,每执行一次计数器累计一次,一直到累加表示部分为False了,整个循环体也就结束了。

  详细逻辑:当程序执行到while语句时,首先要计算表达式的值,如果表达式的值为假,那么结束整个while语句。如果表达式的值为真,则执行语句,执行完成语句再去结算表达式的值;如果表达式的值为假,结束整个while语句,如此循环往复,直到表达式的值为假才停止。对于此,举几个例子。

 

  举例1:循环计算列出1到5这几个数

 # 举例1
num = 1
while num <= 5:
print(num, end="")
num += 1
# 输出结果:12345

  

  举例2:循环计算1到100累计值

 # 举例2
# 计算1-100的累加求和
sum = 0 # 初始化存放容器
num1 = 1 # 初始化计数器
while num1 <= 100:
sum += num1
num1 += 1
# print(sum)
print(sum)
# 输出结果:5050

  举例3:循环把字符串中的每一个字符打印出来。

 # 举例3
# 按顺序打印字符串中的每一个位置
str = "Thomas is a good man"
index = 0 # 计数器初始化
while index < len(str):
print("str[%d] = %s" % (index, str[index]))
index += 1
# 输出结果:
# str[0] = T
# str[1] = h
# str[2] = o
# str[3] = m
# str[4] = a
# str[5] = s
# str[6] = # 这里的空格也是字符串的一个字符
# str[7] = i
# str[8] = s
# str[9] = # 这里的空格也是字符串的一个字符
# str[10] = a
# str[11] = # 这里的空格也是字符串的一个字符
# str[12] = g
# str[13] = o
# str[14] = o
# str[15] = d
# str[16] = # 这里的空格也是字符串的一个字符
# str[17] = m
# str[18] = a
# str[19] = n

  举例4:把一句话循环打印3遍,最终用else:输出一句话来。

 # 举例4
# while语句的第二种形式
a = 1
while a <= 3:
print("Thomas is a good man")
a += 1
else:
print("very very good")

  小结:在while循环控制语句中,一定要注意计数器的叠加情况。这个是控制while循环语句的重中之重。

第二部分:for 循环控制语句

  存在形式如下:

  (1) for 变量名 in 集合:   # 集合可以是range,也可以是一个列表

      语句

  (2) for 变量名 in 集合:

      语句

    else:

      语句    # 只有上面的for循环正常执行完毕,执行下面的else:语句。

  解释如下:

  首先,for循环也是存在两种形式,和while循环一样,最后的else:也是for循环正常执行完毕,执行下面的else:语句。不同点是:for 循环是通过一个变量名在一个集合里面去按照顺序的遍历一遍,遍历结束后这个for 循环体也就结束了。可以理解为:按照顺序取集合中的每一个元素,赋值给变量(这里看明白了,赋值给变量的意思是这个变量的值如果集合没有遍历完毕,一致按照顺序去赋值给变量进行判断,然后复制给变量进行判断,这个赋值的过程,其实我们前面接触到的print遍历一组数,字符,元组等,其实变量的值是处于不断赋值的过程,所以才能让print去打印。)如此循环往复。直到取完这个集合中的元素截止调出循环。

  其次,这里我们看到用到前面所说的range(开始,结束,步长(默认为1)函数,另外后面和这个集合也可以用一个列表[1,2,3,4...]来表示。这就好像我去篮子里面拿鸡蛋,知道拿出最后一个鸡蛋for循环语句也就结束了。

  最后,这里用到了前面说到的成员运算符in ,not in,其实还可用not,is ,is not身份运算符等。其实这里就是个亿逻辑判断。

  这里我们把range函数在说一下:

  函:range

    语:range(self, [,start] [,end] [,step])

      用:start--计数起始位置,end--计数结束位置,step--为计数的步长;如果range内为一个数值,默认表示时从0开始到这个数值,步长为1。这里的range也可以理解为列表生成器,生成数列,注意:所有的集合都是从0开始的序列(如果没有要求的话)

  举例1:把前面while循环语句的1-5个数打印出来,用for循环来表示

 # 举例1
# 遍历打印
for i in [1, 2, 3, 4, 5]:
print(i, end="")
print("\n")
# 输出结果:12345

  举例2:遍历2-20,步长为2的结果。

 # 举例2
# 遍历从2-20,步长为2的结果
for k in range(2, 20, 2):
print(k, end="")
print(" ", end="")
print("k的值是: %d" % k)
print("\n")
# 输出结果:2 4 6 8 10 12 14 16 18 k的值是: 18

  举例3:遍历整个字符串。

 # 遍历字符串
fruits = ['banana', 'apple', 'mango']
for fruit in fruits: # 第二个实例
print ('当前水果 :', fruit)
# 输出结果:
# 当前水果 : banana
# 当前水果 : apple
# 当前水果 : mango

  从这些例子里面可以看出,“遍历”的思路是循环结构中最长使用的方式方法,对于遍历我们前面也讲过一个函数叫enumerate函数,整个函数叫枚举函数,也就是在遍历的时候去记录现在遍历到第几个了。我们把这个函数再复习一下:

  函:enumrate

    语:enumrate(x, [,startNum])

      用:这里的x为枚举哪一个集合,其中startNum可以不写,默认是从0开始的。如果写的话像这样:

        默认:0 就从0 1 2 3 4 5 6 7...这样记录遍历到第几个了。

        设置:1 就是1 2 3 4 5 6 7 8...这样记录遍历到第几个。

        就是一个开始编号的意思。

  举例4:枚举1-5个数。

 # 举例4
# enumerate(x,[,start]) 枚举函数,start枚举开始数字
# 作用:
for index, m in enumerate([1, 2, 3, 4, 5], 1):
# index,m = 下标,元素,for 循环也可以用交换使赋值方式
print(index, m)
# 输出结果:
# 1 1
# 2 2
# 3 3
# 4 4
# 5 5

第三部分: 迭代器(Iterator)

  迭代器这部分内容分可迭代对象和迭代器。其实迭代器从从思想上理解就是循环的一种简写方式。

  可迭代对象:

    可迭代对象:可直接作用于for循环的对象统称为可迭代对象(Iterable,表示可迭代的)

  迭代器

    迭代器:不带可以作用于for循环,还可以被next函数不断调用并返回一个值,直到最后跑出一个stopIteration错误表示无法继续返回下一个值。

        可以被next()函数调用并不断返回下一个值的对象成为迭代器。

  函:isinstance()

    语:range(对象,识别类型)

      用:这个函数可以识别iterable那些可以迭代,iterator那些可以作为迭代器。

from collections.abc import Iterable,Iterator

# 那些可以作为迭代对象
print(isinstance([],Iterable))
print(isinstance((),Iterable))
print(isinstance({},Iterable))
print(isinstance("",Iterable))
print(isinstance((x for x in range(10)),Iterable))
print(isinstance(1,Iterable)) # 迭代器有哪些?
print(isinstance([],Iterator))
print(isinstance((),Iterator))
print(isinstance({},Iterator))
print(isinstance("",Iterator))
print(isinstance((x for x in range(10)),Iterator)) # 这是一个迭代器
print(isinstance(1,Iterator))

  我们从返回值可以看出,除了1不能作为迭代对象,其他都可以作为迭代对象;但是iterator能作为迭代器的只有迭代表达式。

  补充说明:

  我们需要导入一个collections库才能用isinstatnce函数,但是在Python3更高级的版本中调用这个库会产生错误。因为这个库的名字已经更改了。

  旧版:from collections import iterable,iterator

  新版:  from collections.abc import iterable,iterator   # 增加了一个abc后缀,这里要特别说明。

  函:iter()

    语:iter(把什么内容变成可迭代内容,)

      用:如果当前的内容不是要给迭代器,那么我们可以把什么内容转换为迭代器,后面内容不是唯一的用逗号进行分割。

  函:next()

    语:next(迭代器句柄)

      用:这个函数不是可以一次一次的进行迭代。

  举例说明:

# 迭代形式的使用
l = (x for x in range(5))
print(next(l))
print(next(l))
print(next(l))
print(next(l))
print(next(l))
# print(next(l)) # 报错了
# 返回0 1 2 3 4 迭代了4次
# 这里的迭代格式为x for x in range() # 使用迭代器,转换想要迭代的内容
a = iter([1,2,3,4,5])
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))
# 返回 1 2 3 4 5 迭代了5次 # 案例:
endstr = "end"
line = "\t"
str1 = ""
for str in iter(input,endstr):
str1 = str1 + str
if str == endstr:
break
str1 = str1 + line
print("您输入的内容是:%s" %str1) # 解释:iter生成一个迭代内容(input,endstr),在这就好比一个循环内容,到最后一个循环
# endstr的时候结束,也就是说一直循环input1,input2,input3...,endstr最后一个输入
# end字符串结束 # 输出内容:
# Thomas
# is
# a
# good
# man
# end
# 您输入的内容是:Thomas is a good man

  因此我们可以看到迭代器不光可以迭代数据类型,还可以迭代一个函数,最后一个例子当中迭代了input这个函数

第三部分:生成器(generator)

  生成器我们要记住一个函数叫做yeild,这个函数是相对于return这个来讲的。return这个表示函数结束并返回,yield这个表示暂停的意思。我们通过段函数来说明这个问题:

  第一段:正常的return

def r(n):
print("Hello,return")
while n>:
print("before return")
return n
n -=
print("after return")
r()
# 返回值:
# Hello,return
# before return

  我们可以看到碰到return整个值就反回了,不在执行。

  第二段:改为yield的代码

def y(n):
print("Hello,yield")
while n>:
print("before yield")
yield n
n -=
print("after yield")
yy = y()
yy.__next__() # 注意:在python2,next前后是没有双划线的
yy.__next__()
yy.__next__()
yy.__next__() # 报错,执行到第三遍
# 返回值:
# Hello,yield
# before yield
# before yield
# after yield
# before yield
# after yield
# StopIteration # 报错,执行到第三遍

总结:

  这样这两个循环体就解释完了,总结有一下两点注意:

  1. for语句中的"for 表达式 in 集合:"这句话是两句话的缩写
  第一句:表达式1 = 集合中的第一个元素,表达式2 = 集合中的第一个元素 ... ...实际是一个赋值语句
  第二句:当全部赋值完毕结束整个for循环语句
  因此:遍历过程其实是把整个赋值后的表达式打印出来,但是这个值的位置只有一个,赋值——覆盖——赋值——覆盖——最后一个运算值。

  2. 既然是表达式赋值方式,所以for循环也可用交互式赋值方式。

  3. 同样for的表达式后也要加上“:”