语句与流程控制
for 语句
for循环取值的时候,其实内部就是用next取值的,只是封装了,我们看不到
Python中的for语句能够遍历任何序列的项目,例如列表或字符串。
语法
for iterating_var in sequence:
statements(s)
Python
可以直接作用于for循环的数据类型有以下几种:
一类是集合数据类型,list,tuple,dict,set.str等
一类是generator,包括生成器和带yield的generator function
*这些可以直接着用于for循环的对象统称为可迭代对象:Iterable
*可以被next()函数调用并不断返回下一个值得对象称为迭代器:Iterator
通过iter方法把可迭代对象,变成为迭代器
a = [1,2,3,5] # 可迭代的对象
print(iter(a)) # 转换
可以使用isinstance()判断一个对象是否是Iterable
break 语句用于跳出最近的一级 for 或 while 循环
迭代器
迭代器是访问集合内元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素都被访问一遍后结束。
迭代器的另一个优点就是它不要求你事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代至某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件,或是斐波那契数列等等。这个特点被称为延迟计算或惰性求值(Lazy evaluation)。
迭代器更大的功劳是提供了一个统一的访问集合的接口。只要是实现了__iter__()方法的对象,就可以使用迭代器进行访问
next(iterator[, default])
1. 函数必须接收一个可迭代对象参数,每次调用的时候,返回可迭代对象的下一个元素。如果所有元素均已经返回过,则抛出StopIteration
异常。
>>>a = iter("abcd")
>>>next(a)
'a'
>>>next(a)
'b'
>>>next(a)
'c'
>>>next(a)
'd'
>>>next(a)
Traceback(most recent call last):
File "", line 1, in
StopIteration
2.Python 的 for 语句依据任意序列(链表或字符串)中的子项,按它们在序列中的顺序来进行迭代。
>>> # Measure some strings:
... words= ['cat','window','defenestrate']
>>> forw in words:
... print(w,len(w))
...
cat 3
window 6
defenestrate 12
如果你想要修改你迭代的序列,你可以迭代它的复本。使用切割标识
>>> forwinwords[:]: # Loop over a slice copy of the entire list.
... iflen(w) > 6:
... words.insert(0,w)
...
>>> words
['defenestrate', 'cat', 'window', 'defenestrate']
range 范围 # 3.0上range就是一个迭代器
1.一般用于生成数值序列,以便执行特定次数的循环
>>> r = range(5) # range是序列里面不可变序列类型,不支持原位改变
>>> r
range(0, 5)
>>> type(r)
>>>for i in range(5):
print("wangxueya")
wangxueya
wangxueya
wangxueya
wangxueya
wangxueya
>>>for i in range(5):
print("wangxueya" + str(i))
wangxueya0
wangxueya1
wangxueya2
wangxueya3
wangxueya4
>>> z = range(1,10,2) # 1到10,隔两位赋值
>>> z
range(1, 10, 2)
>>> for i in z:
print(i)
1
3
5
7
9
内置的函数range()是对一系列数字进行迭代的函数。它生成一个算术进化的迭代器。
示例
>>> range(5)
range(0, 5)
>>> list(range(5))
[0, 1, 2, 3, 4]
示例
range()生成一个迭代器,以处理0到n-1的整数。要获取序列的列表对象,可将其列为list()。现在可以使用for语句迭代此列表。
>>> for var in list(range(5)):
print (var)
Shell
上面示例代码将产生以下输出 -
0
1
2
3
4
Shell
示例
#!/usr/bin/python3
for letter in 'Python': #traversal of a string sequence
print ('Current Letter :', letter)
print()
fruits = ['banana', 'apple', 'mango']
for fruit in fruits: # traversal ofList sequence
print ('Current fruit:', fruit)
print ("Good bye!")
Python
当执行上述代码时,会产生以下结果 -
Current Letter : P
Current Letter : y
Current Letter : t
Current Letter : h
Current Letter : o
Current Letter : n
Current fruit : banana
Current fruit : apple
Current fruit : mango
Good bye!
# 整列表循环
name = ["tom","jerry","mike","peter","john"]
for i in name: # 列表几个元素,循环几次列表
print(name)
['tom', 'jerry', 'mike', 'peter']
['tom', 'jerry', 'mike', 'peter']
['tom', 'jerry', 'mike', 'peter']
['tom', 'jerry', 'mike', 'peter']
['tom', 'jerry', 'mike', 'peter']
# 列表元素依次循环
name = ["tom","jerry","mike","peter","john"]
for i in name:
print(i)
tom
jerry
mike
peter
john
for i in range(1,6):
print(i**2)
1
4
9
16
25
#猜数字
while True:
txt = input("请输入数字。。。")
if txt == "stop":
break
# .isdigit是用于判断当前字符串是不是一个数字,如果是返回True,不是返回False
elif not txt.isdigit(): # 加not是取反
print("你输入的不是数字。。。")
else:
num = int(txt)
if num<20:
print("你输入的值小了")
elif num>20:
print("你输入的值太大了")
else:
print("恭喜guess正确")
enumerate
a = [1,3,5]
for i in enumerate(a): print(i)
(0, 1) # 通过enumerate的使用,把每个元素的下标位置打印出来
(1, 3)
(2, 5)
#另一列子
list = ["Iphon:",5800],["milk:",10]
for i,list in enumerate(list): print(i,list)
0 ['Iphon:', 5800]
1 ['milk:', 10]
或者使用len()
>>> a = ['Mary','had','a','little','lamb']
>>> fori in range(len(a)):
... print(i,a[i]) # 注意 a是list
...
0 Mary
1 had
2 a
3 little
4 lamb
按序列索引迭代
迭代遍历每个项目的另一种方法是通过索引偏移到序列的索引位置。以下是一个简单的例子 -
示例
#!/usr/bin/python3
fruits = ['banana', 'apple', 'mango']
for index in range(len(fruits)):
print ('Current fruit :', fruits[index])
print ("Good bye!")
Python
当执行上述代码时,会产生以下结果 -
Current fruit : banana
Current fruit : apple
Current fruit : mango
Good bye!
Python
在这里调用内置len()函数,该函数计算元组中的元素总数以及内置range()函数提供了迭代的实际顺序。
循环中使用else语句
Python支持在循环语句中关联else语句。
· 如果else语句与for循环一起使用,则只有在for循环正常终止(而不是遇到break语句)时才执行else块。
· 如果else语句与while循环一起使用,则在条件变为false时执行else语句。
示例
以下示例说明了使用else语句在for循环中,搜索列表中的偶数的用法。
#!/usr/bin/python3
numbers = [11,33,55,39,55,75,37,21,23,41,13]
for num in numbers:
if num%2 == 0:
print ('the list contains an even number')
break
else:
print ('the listdoesnot contain even number')
Python
当执行上述代码时,会产生以下结果 -
the list does not contain even number
总结: for循环用来控制循环次数,主体中可以定义每次循环你想要做的事情。
通过try、except和else的使用来使Python程序更加“强壮”
try:执行可能会出错的试探性语句,即这里面的语句是可以导致致命性错误使得程序无法继续执行下去
except:如果try里面的语句无法正确执行,那么就执行except里面的语句,这里面可以是错误信息或者其他的可执行语句
else:如果try里面的语句可以正常执行,那么就执行else里面的语句(相当于程序没有碰到致命性错误)
raw = input()
try:
num = int(raw+"10")
except Exception :
print("输入有误")
else:
print("正确执行",num)
列表生成器
1. 列表生成器只有在调用的时,才会生成相应的数据
2. 生成器只记录当前生成的位置,只有一个__next__()方法
a = [i*2 for i in range(10)] #这是列表生成式
print(a)
[0, 2, 4, 6, 8, 10,12, 14, 16, 18]
类似与:
for i in range(10):
b.append(i*2)
print(b)
[0,2, 4, 6, 8, 10, 12, 14, 16, 18]
# 如果要依次增加则就在循环内print
b = [] # 先定义一个空列表
for i in range(5):
b.append(i*2)
print(b)
[0]
[0, 2]
[0, 2, 4]
[0, 2, 4, 6]
[0, 2, 4, 6, 8]
斐波那契数列
def fib(c): #这本身就是一个算法
n, a,b = 0,0,1 # a = b, b =a+b
while n <c:
print(b) # 只打印b,b就是斐波那契数列
a,b = b,a+b # 类似与 a = [b] b = [a+b]
n = n+1
fib(10) # 循环十次
1
1
2
3
5
8
13
21
34
55
def fib(c):
n, a,b = 0,0,1
while n <c:
#print(b)
# 每print(f.__next__())之后到这结束
yield b # 只要有yield 那么就不是函数了是生成器
#yield 还用于保存当前状态,并返回
a,b = b,a+b # 类似与 a = [b] b = [a+b]
n = n+1
# return "done" # 异常的时候,返回值down
f = fib(10)
print(f.__next__()) # 每print一次产生新的一个值
print("----------") # 可让生成器停在yield,跳出生成器再干点其他的事
print(f.__next__()) # 每print(f.__next__())一次执行函数
print(f.__next__())
print(f.__next__()) # 当print超出10个就会抛出StopIteration 异常
print("----startfor-----")
for i in f: # 剩下的由for循环打印
print(i)
1
----------
1
2
3
----start for-----
5
8
13
21
34
55
# 异步IO雏形 单线程进行多任务 协程
def consumer(name):
print("%s准备吃包子"%name)
while True:
baozi = yield
print("包子%s来了,被%s吃了"%(baozi,name))
c = consumer("王者") # 这一步把函数变成了生成器
c.__next__() # 开始执行生成器
b1 = "韭菜馅"
c.send(b1) # 调用yield 并进行赋值
c.__next__() # 调用yield 但不进行赋值
import time
def producer(name):
c = consumer("甲")
c2 = consumer("已")
c.__next__()
c2.__next__()
print("开始准备做包子了")
for i in range(1,4):
time.sleep(2)
print("做了2个大包子")
c.send(i)
c2.send(i)
producer("乾坤")
王者准备吃包子
包子韭菜馅来了,被王者吃了
包子None来了,被王者吃了
甲准备吃包子
已准备吃包子
开始准备做包子了
做了2个大包子
包子1来了,被甲吃了
包子1来了,被已吃了
做了2个大包子
包子2来了,被甲吃了
包子2来了,被已吃了