- 学习先导
-
作用:
- 选择性执行语句。条件为真,执行if下的语句块,若存在elif则继续判断,当判断至else则执行else下的语句块。
-
if-else常规语句
-
语法:
if 真值表达式: 语句块1 else: 语句块2
- 运行机理:本质判断是,
if 布尔值,实际中运行的是if bool(obj),比如if 100为if bool(100)
- 运行机理:本质判断是,
-
-
if-elif-else多条件判断语句
-
语法:
if 真值表达式: 语句1 elif 真值表达式2: 语句2 elif 真值表达式3: 语句3 ... else: 语句块4
-
-
条件表达式(三元表达式)
-
作用:同样进行执行控制,但更灵活简洁
-
语法:
<表达式1> if <真值表达式> else <表达式2>
-
返回:若真值表达式为真,则返回表达式1结果,否则返回表达式2结果
<表达式1,为真返回> if <真值表达式> else <表达式2,为假返回>- 注意:
表达式1和表达式2返回的是表达式计算完毕的结果。 示例:
- 注意:
-
L = [1, 2, 3]
i = 4
a = L[0] if True else L[i]注意:表达式不是语句,表达式能赋值给变量,语句则不能。此在第一章语句和表达式已有详细描述。
示例1:
a = 25
if 0 <= a < 18:
print('未成年')
elif a < 30:
print('年轻人')
else:
print('不再年轻')运行结果:
年轻人
示例2:
# 条件表达式
print('a' if True else 'b')
print('a' if False else 'b')
# 使用条件表达式计算绝对值
n = -20
m = n if n > 0 else -n
print(m)运行结果
a
b
20
填充语法空白
示例:if语句中的使用
if Ture:
pass
else:
print('输入有问题')格式:
while <真值表达式1>:
语句1
else <真值表达式2>:
语句2运行机制:
- 第一行while一行中,计算判断<真值表达式1>。
- 若为True,则执行完后面语句后又跳回while一行,重新计算判断<真值表达式1>。
- 若为False,则执行else语句,else语句可以省略。
示例1:循环结束后更改while的判断和使用值
a = 0
while a < 6:
print(a, end=' ')
a += 1
# 0 1 2 3 4 5示例2:while-True用法
# code1:
a = 3
while True:
if not a:
break
print(a, end=' ')
a -= 1
print('exit:', a)
# 3 2 1 exit: 0
# code2:
a = 3
while a:
print(a, end=' ')
a -= 1
print('exit:', a)
# 3 2 1 exit: 0示例3:警惕while循环一开始就改变使用值
code1: 简易示例
a = 3
while a:
a -= 1 # 警惕while结构中在一开始就改变值的语句
print(a, end=' ') # 后续使用可能都会错位一个值,造成逻辑错误
print('exit:', a)
# 运行结果:2 1 0 exit: 0code2: 数据处理的逻辑错误
i = 0
L = [(1, 45.3), (2, 33.4), (3, 66.6), (None, None)]
num, data = L[i]
print('[%s '% data, end=' ')
print('%s]' % int(data), end=' ')
while num != None:
i += 1
num, data = L[i]
print('[%s '% data, end=' ')
print('%s]' % int(data), end=' ')
# 运行结果:[45.3 45] [33.4 33] [66.6 66] [None ......(后续报错信息)code3:纠正
i = 0
L = [(1, 45.3), (2, 33.4), (3, 66.6), (None, None)]
num, data = L[i]
while num != None:
print('[%s '% data, end=' ')
print('%s]' % int(data), end=' ')
i += 1
num, data = L[i]
# 运行结果:[45.3 45] [33.4 33] [66.6 66]-
作用:循环遍历,返回可迭代“对象”元素
-
格式:
for <变量列表> in <可迭代对象>: 语句块1 else: 语句块2
<变量列表>可以直接用多个变量接收,相当于第一章中几种赋值方式中的多重赋值- else语句块可以存在,它在循环正常执行结束后将执行。
示例:
for a in [(0, '001'), (1, '002'), (2, '003')]:
print('a:', a)
print('-'*13)
for n, a in [(0, '001'), (1, '002'), (2, '003')]:
print('n:', n, ', a:', a)
print('-'*13)
for i in range(3, 6):
print(i, end=' ')运行结果:
a: (0, '001')
a: (1, '002')
a: (2, '003')
-------------
n: 0 , a: 001
n: 1 , a: 002
n: 2 , a: 003
-------------
3 4 5
- 格式:
range(s, e, step)- s--开始数值, e--结束数值(不包含), step--步数(可为负数)
- 规则类似于序列操作中的切片
- 返回:
- 返回数值序列的“可迭代对象”, 非序列
- 特性:
- 等差数列。
- 惰性计算,非一次性将所有数据计算存储于内存中。
示例:3个参数的常规使用
it = range(3, 6)
print('it:', it) # range(3, 6)
for i in range(3, 6):
print(i, end=' ')
print('\n---------------')
print('3:7:1 ', list(range(3, 8))) # 3,4,5,6,7
print('3:7:2 ', list(range(3, 8, 2))) # 3,5,7
print('3:0:1 ', list(range(3, 0))) # 无
print('3:0:-1 ', list(range(3, 0, -1))) # 3,2,1运行结果:
it: range(3, 6)
3 4 5
---------------
3:7:1 [3, 4, 5, 6, 7]
3:7:2 [3, 5, 7]
3:0:1 []
3:0:-1 [3, 2, 1]
示例:range的数据是惰性计算的 —— range的特性测试
from datetime import datetime as dt
t0 = dt.now()
print(range(4*10**7)[-1])
print('耗时:%s秒'%(dt.now() - t0).total_seconds())
t0 = dt.now()
print(list(range(4*10**7))[-1])
print('耗时:%s秒'%(dt.now() - t0).total_seconds())运行结果:
39999999
耗时:0.000997秒
39999999
耗时:1.756992秒
for <变量列表> in <可迭代对象>:
语句块1
else:
语句块2-
for语句中的in的真正含义:for ... in ...语句中的in不同于操作运算符in;- 操作运算符
in是判断某数据是否存在于某个数据容器或可迭代对象中; - 而for语句中的in则是指在当前这个可迭代对象中逐个取值。
-
for语句中的可迭代对象变化带来的影响:for ... in <可迭代对象>中的<可迭代对象>内的数据可以发生改变。- 对于序列,长度和内部数据均可以改变,但对于集合,仅能改变内部数据,如果长度发生变化将导致触发异常。
- 其中,需要注意对于可变序列(列表)的长度变化,若循环中长度一直增加,将有可能造成无限循环。
- 它们迭代取值是按照
<可迭代对象>索引来取值的。- 下面的示例,对于有序序列(列表)严格按照索引向后取值,但对于集合等无序数据容器则难以找到规律。
- 因此在实际使用中最好不要在for语句中直接将可迭代对象进行变化,可以尝试浅拷贝或深拷贝后再进行遍历。
-
for语句的实现原理:for语句的本质:使用迭代器方法取出数据。- 使用while、迭代器、next()以及try捕获异常实现,该详细介绍见下一章迭代器之for语句的本质
code1:
print('for循环探索')
i = 6
for x in range(1, i): # 此处in是什么含义?
# for ... in ... 迭代[1,i)
# 每个循环向后逐个取出元素,赋值给x
print('x=', x, ' i=', i)
i -= 1
print('while循环探索')
i = 6
x = 1
while x in range(1, i): # 此处in是什么含义?
# ... in ... 判断x是否在[1,i)内
print('x=', x, ' i=', i)
x += 1
i -= 1运行结果:
for循环探索
x = 1 i = 6
x = 2 i = 5
x = 3 i = 4
x = 4 i = 3
x = 5 i = 2
while循环探索
x = 1 i = 6
x = 2 i = 5
x = 3 i = 4
code2: in的正确使用示例
print('for循环探索')
i = 6
it = range(1, i)
for x in it:
if x in it: # in判断操作,判断x是否在[1,i)内
print('x=', x, ' i=', i)
i -= 1
it = range(1, i)
else:
break
print('while循环探索')
i = 6
it = range(1, i)
while x in it: # in判断操作,判断x是否在[1,i)内
x = next(it)
print('x=', x, ' i=', i)
i -= 1
it = range(1, i)运行结果:
for循环探索
x= 1 i= 6
x= 2 i= 5
x= 3 i= 4
while循环探索
x= 1 i= 6
x= 2 i= 5
x= 3 i= 4
code1: 列表有规律可寻,是按照位置索引向下逐渐取值的
L = [1, 2, 3]
for x in L:
print(x, L, end=' --> ')
L.remove(x) # 此行注释将导致无限循环
L.append(x+10)
print(L)1 [1, 2, 3] --> [2, 3, 11]
3 [2, 3, 11] --> [2, 11, 13]
13 [2, 11, 13] --> [2, 11, 23]
code1: 列表探索
# for语句自动迭代
a = [1, 2, 3, 4, 5, 6]
Index = 0
for item in a:
print(Index, item, a, end=' --> ')
a.remove(item)
print(a)
Index += 1
print('a最终结果:', a)
# 使用迭代器步进,此为for循环语句的本质
a = [1, 2, 3, 4, 5, 6]
it = iter(a)
Index = 0
while True:
try:
item = next(it)
print(Index, item, a, end=' --> ')
a.remove(item)
print(a)
Index += 1
except StopIteration:
break
print('a最终结果:', a)运行结果:
0 1 [1, 2, 3, 4, 5, 6] --> [2, 3, 4, 5, 6]
1 3 [2, 3, 4, 5, 6] --> [2, 4, 5, 6]
2 5 [2, 4, 5, 6] --> [2, 4, 6]
a最终结果: [2, 4, 6]
(运行结果以上一共重复2次)
code2: 集合探索
# for语句
a = {1, 2, 3, 4, 5, 6}
Index = 0
for item in a:
print('%3d, %3d'%(Index, item), a, end=' --> ')
a.remove(item)
a.add(item+100)
print(a)
Index += 1
print('a最终结果:', a)
# 迭代器步进
a = {1, 2, 3, 4, 5, 6}
it = iter(a)
Index = 0
while True:
try:
item = next(it)
print('%3d, %3d'%(Index, item), a, end=' --> ')
a.remove(item)
a.add(item+100)
print(a)
Index += 1
except StopIteration:
break
print('a最终结果:', a)code3: 从集合中取值,无法捕捉索引规律。
- 可能与存储的数据有关系,不同的值造成取值次数不同
- 集合取值的进一步验证失败,猜想跟哈希计算有关,需要待进一步探索。
def veri(s):
id_all = {}
index_all = []
print('')
for x in s:
print('- 原始结果:', s)
index_all.append(list(s).index(x))
print(index_all, '第%s次' % len(index_all))
ids = dict(zip([id(x) for x in s], s))
id_all.update(ids)
# print(id_all)
# print(dict(sorted(id_all.items(), key=lambda x:x[0])))
print('id列表:', ids)
# print('id排序:', dict(sorted(ids.items(), key=lambda x:x[0])))
print(x, s, end=' --> ')
s.remove(x)
s.add(x+10)
# s.update({x+10})
print(s)
veri({1000, 2000, 3000}) # 会取出4次
veri({1000, 2000, 10000}) # 会取出5次如何在循环中让程序不再向下执行,重新开始一次新的循环?
- 使用continue语句。
说明:
- for循环中迭代取下一个元素。
break语句 退出当前语句块
- 注意1:
break不干扰外层其他语句块
- 注意2:
- break作用范围是整个
for-else、while-else语句块。 - 在
for-else和while-else语句中break退出整个语句块。即for-else和while-else中else的语句也被跳过。
- break作用范围是整个
示例1:内部只能执行1次,外部2次无干扰
for i in range(2):
print(i)
for j in ['a', 'b', 'c']:
print('j:', j)
if j == 'a':
break运行结果:
0
j: a
1
j: a
示例2:break作用范围是整个for-else、while-else语句块
code1:
for i in [1, 2, 3, 4]:
if i==2:
continue # 见下一节
print(i)
else:
print("hello")结果为
1
3
4
hello
code2:
for i in [1, 2, 3, 4]:
if i==2:
break
print(i)
else:
print("hello")结果为
1
返回:布尔值或表达式计算结果对象
运算符:not、and、or
常见使用方法:常与 if 联用,如 if <条件表达式1> or <条件表达式2>,等价于 if bool(<条件表达式1> or <条件表达式2>)
用法:
-
布尔非操作:
not x>>> not True False
-
布尔与操作:
x and y优先返回假值对象。
机理:从左到右依次运算,返回第一个假值对象。
从左到右依次运算,只要有一个条件表达式满足假值条件,就返回当前计算结果值。 -
布尔或操作:
x or y优先返回真值对象。
机理:从左到右依次运算,返回第一个真值对象。
从左到右依次运算,只要有一个条件表达式满足真值条件,就返回当前计算结果值。
示例1:
>>> 0 and 20 and 1 # 优先返回假值对象
0
>>> 20 and 0 and 1
0
>>> 0 and False and None and [] and 100 and 200 and 300
0
>>> 0 or 20 or 1 # 优先返回真值对象
20
>>> 20 or 0 or 1
20
>>> 0 or False or None or [] or 100 or 200 or 300
100示例2:and与or的计算顺序对比
code1: and返回第一个假值
L = []
def func(x):
L.append(x)
jd = 1+2 and func(3) and func(4)
print(jd) # None
print(L) # [3]code2: or返回第一个真值
L = []
def func(x):
L.append(x)
return None
jd = 1+2 or func(3) or func(4)
print(jd) # 3
print(L) # []+(正号)
-(负号)
一元运算符
语法:+/- 表达式