• 参考书《Python基础教程(第三版)》—— Magnus Lie Hetland

文章目录

  • ​​一、再看print和import​​
  • ​​1. print()函数​​
  • ​​2. import​​
  • ​​二、特殊赋值方法​​
  • ​​1. 序列解包​​
  • ​​2. 链式赋值​​
  • ​​3. 增强赋值​​
  • ​​三、条件和条件语句 if-elif-else​​
  • ​​1. 布尔值​​
  • ​​2. 条件语句​​
  • ​​3. 布尔表达式​​
  • ​​4. 断言​​
  • ​​四、循环语句​​
  • ​​1. while循环​​
  • ​​2. for循环​​
  • ​​3. 迭代工具​​
  • ​​(1)并行迭代 zip()​​
  • ​​(2)迭代时获取索引​​
  • ​​(3)反向迭代和排序后再迭代​​
  • ​​4. 跳出循环​​
  • ​​五、简单推导和字典推导​​
  • ​​六、其他语句del/pass/exec/eval​​
  • ​​1. pass语句​​
  • ​​2. exec语句​​
  • ​​3. eval语句​​
  • ​​4. del语句​​

一、再看print和import

1. print()函数

  1. 原型​​print( para,para,..,(sep = para),(end = para) ):none​
  2. print()可以打印一个表达式,这个表达式要么是字符串,要么自动转为字符串形式打印
  3. print()中可以填任意多个参数,关键字实参​​sep​​​和​​end​​可以缺省
  1. ​sep​​指定打印的两个参数间的间隔符缺省为空格' '
  2. ​end​​指定打印的字符串的后缀缺省为换行符'\n'
#缺省sep和end
>>> print('A',1,2)
A 1 2

#设置sep为'_'
>>> print('A',1,2,sep = '_')
A_1_2

#设置sep和end
>>> print('A',1,2,sep = '_',end = '*')
A_1_2*

#end尾缀可以是字符串
>>> print('A',1,2,sep = '_',end = 'AAAA')
A_1_2AAAA

2. import

  1. 从模块导入
  1. 导入一个模块:import 模块名
  • 调用方法/函数:​​模块名.方法/函数名()​​,这里是方法/函数的引用
  • 访问属性:​​模块名.属性名​​,这里是原属性的引用
  1. 导入一个模块中的所有属性和方法/函数:from 模块名 import *
  • 调用方法/函数:​​方法/函数名()​​,这里是方法/函数的引用
  • 访问属性:​​属性名​​,这里是原属性的拷贝
  1. 导入某个方法:from 模块名 import 方法名
  2. 导入某几个方法:from 模块名 import 方法名1,方法名2,方法名3
  1. 如果有两个模块包含一样的方法名(如open)
  1. 给模块起别名:improt 模块名 as 别名
  2. 给方法起别名:from 模块名 import 方法名 as 别名

二、特殊赋值方法

1. 序列解包

  1. 序列解包:将一个序列或任何可迭代对象解包,并将得到的值存储到一系列变量中
>>> values = 1,2,3
>>> values
(1, 2, 3)

#对元组进行解包
>>> x,y,z = values
>>> x,y,z
(1, 2, 3)
>>> x
1
>>> x,y
(1,2)

#利用序列解包交换变量值
>>> x,y = y,x
>>> x,y,z
(2, 1, 3)
  1. 序列解包在使用返回元组(或其他数列、可迭代对象啊)的函数/方法时很有用
>>> items = {'name': 'Tom', 'age': 18}
>>> key,value = items.popitem() #字典的popitem()方法,任意弹出字典中一个键值对
>>> key
'age'
>>> value
18
  1. 收集参数
  1. 使用序列解包时,要确保左边给出的目标数目和被解包序列元素个数相同,否则出错
  2. “带*变量” 收集多余的序列元素,这样带*变量得到一个列表
  3. 这种方法可以用到函数参数列表中
>>> A,B = [1,2,3,4]  #报错

>>> A,B,*rest = [1,2,3,4]
>>> rest
>>> [3,4]

>>> A,B,*rest = [1,2,3]
>>> rest
>>> [3]

>>> A,*rest,B = [1,2,3,4,5]
>>> rest
>>> [2,3,4]

2. 链式赋值

x = y = somefunction()  
#等价于
y = somefunction()
x = y

3. 增强赋值

  • 可以使用​​+=​​​和​​-=​​,类似C++
>>> a = 10
>>> a += 2
>>> a
12

>>> str = 'ABC'
>>> str += 'D'
>>> str
'ABCD'

三、条件和条件语句 if-elif-else

1. 布尔值

  1. 标准真值是True/False​,它们是1和0的别名
>>> True+1
2
>>> False == 0
True
  1. 用作布尔表达式时
  1. 以下被解释为False:​​False​​​ / ​​None​​​ / ​​0​​​ / ​​''​​​ / ​​()​​​ / ​​[]​​​ / ​​{}​
  2. 其他被解释为True
  1. bool和list一样,可以用来转换其他值构造bool类型
>>> bool("ABC")
>>> True

>>> bool('')
False

2. 条件语句

  • ​if-elif-else​​结构
if expression1:
# code
elif expression2:
# code
...
elif expressionN:
# code
else:
# code

3. 布尔表达式

  1. 比较运算符

符号

说明

传统比较运算符

​==​​​ / ​​!=​​​ / ​​>​​​ / ​​<​​​ / ​​>=​​​ / ​​<=​

类似C/C++中的比较符号

链式比较

​1 <= number <= 10​

等价于​​1 <= number && number <= 10​

对象比较

​is​​​ / ​​is not​

比较两个对象是否为同一个对象;而​​==​​比较两个对象是否相等 (不可将is用于比较数和字符串等不可改变的基本值,鉴于python在内部处理这些对象的方式,这样做的结果是不可预测的)

成员资格检查

​in​​​ / ​​not in​

如​​x in y​​检查x是否为容器y的成员

# '=='检查两个对象是否相等
# 'is'检查两个对象是否相同(“指向同一个对象” / 或者时说“是同一个对象”)
>>> x = y = [1,2,3] # 等价于y = [1,2,3], x = y
>>> z = [1,2,3]

>>> x == y
True
>>> x == z
True
>>> x is y
True
>>> x is z
False
  1. 字符串和序列的比较
  1. 字符串是根据字符的字母排序进行比较的
  2. 本质上比较的是unicode编码,字符是按码点排列的
  • 可以用ord(char)返回字符的Unicode值
  • 可以用chr(int)将Unicode值转为字符返回
  1. 序列的比较方式也是这样的
>>> ord('A') 
65
>>> chr(65)
'A'

>>> [1,2]<[2,1]
True
>>> [2,[1,4]]<[2,[1,5]]
True
  1. 逻辑运算符
  1. 逻辑运算符用来连接多个布尔表达式,构成复合条件表达式
  2. python中的逻辑运算符:​​and / or / not​
  3. python的符合条件语句也有短路特性

运算符

操作

说明

​and​

与运算

类似C中​​&&​

​or​

或运算

类似C中​​||​

​not​

非运算

类似C中​​!​

4. 断言

  1. 断言是if的“亲戚”,伪代码类似如下:
# 断言的伪代码
if not condition:
crash program
  1. 断言的目的在于在程序出错时立刻崩溃,而不是错误隐藏到之后再崩溃
  2. 基本上,可以用断言要求某些条件得到满足,比如判断参数合法
  3. 断言的形式​​assert 条件表达式 (,'报错字符串')​
# 条件满足,断言报错不被触发
>>> age = 10
>>> assert 0 < age < 100

# 条件不满足,触发断言报错
>>> age = -1
>>> assert 0 < age < 100
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError

#可以在assert断言后加一个说明字符串,这样报错的时候可以看到说明
>>> age = -1
>>> assert 0 < age < 100, "Age Error"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: Age Error

四、循环语句

1. while循环

while 判断条件:
循环体

2. for循环

  1. 基本上,可迭代对象是可以用for循环遍历的对象。(后面再介绍迭代器,目前把可迭代对象视为序列即可)
# 遍历列表打印
words = ['apple','big','car']
for word in words:
print(word)

numbers = [1,2,3,4,5,6,7,8,9,10]
for num in numbers:
print(num)
  1. 为了方便遍历特定范围的数据,python提供内置函数​​range(begin,end)​
>>> range(0,10)
range(0,10)
>>> list(range(0,10))
[0,1,2,3,4,5,6,7,8,9]

>>> list(range(5))
[0,1,2,3,4,5]
  1. 还可以加上步进长度参数​​range(begin,end,step)​
>>> list(range(10,0,-1))
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

>>> list(range(10,0,-2))
[10, 8, 6, 4, 2]

>>> list(range(10,0,-3))
[10, 7, 4, 1]
  1. 可以用类似序列的方法用for循环遍历字典,但是字典内部是没有顺序的,所有这样for循环打印的顺序是不一定的,只能保证所有值都被处理。如果顺序很重要,可以把键或值存入一个列表,对列表进行排序,再迭代
#打印所有键值对
d = {'x':1,'y':2 }
for key in d:
print(key,":",d[key])

#打印所有键值对(使用了序列解包)
d = {'x':1,'y':2 }
for key,value in d.items():
print(key,":",value)

3. 迭代工具

  • python提供了一系列可以帮助迭代的函数,其中一些位于​​itertools​​模块中,另外还有一些内置函数

(1)并行迭代 zip()

  • 有时候可能想并行迭代两个序列,可以用​​zip(a,b,c...)​​把任意多个序列"缝合"起来,并返回一个由元组组成序列可以把它转换为列表查看
  • 当被缝合的序列长度不同时,zip将只缝合并返回最短序列长度个元素
>>> list1 = [1,2,3]
>>> list2 = ['A','B','C']
>>> list3 = [4,5,6,7,8,9]
>>> list(zip(list1,list2,list3))
[(1, 'A', 4), (2, 'B', 5), (3, 'C', 6)]
  • zip配合序列解包,可以方便地进行多序列并行迭代
#不使用zip
names = ['Tom','Bill','Jack']
ages = [12,20,18]
for i in range(len(names)):
print(names[i],'is',ages[i],'years old')

#使用zip
names = ['Tom','Bill','Jack']
ages = [12,20,18]
for name,age in zip(names,ages):
print(name,'is',age,'years old')

(2)迭代时获取索引

  • 利用​​enumerate(可迭代对象)​​函数:返回一个由元组组成序列每个元组是由索引和元素值组成,用list()可以把这个序列转为元组列表。
>>> list(enumerate(['A','B','C','D'])) 
[(0, 'A'), (1, 'B'), (2, 'C'), (3, 'D')]

>>> list(enumerate('string'))
[(0, 's'), (1, 't'), (2, 'r'), (3, 'i'), (4, 'n'), (5, 'g')]

# 一个示例 ------------------------
lst = ['BBC','CCTV','ABC']
for index,item in enumerate(lst):
if 'B' in item:
lst[index] = 'X'

print(lst) # 打印['X', 'CCTV', 'X']

(3)反向迭代和排序后再迭代

  • python提供了两个内置函数​​reversed(可迭代对象):list_reverseiterator object​​​和​​sorted(可迭代对象):list​​,它们不修改原对象,而是返回反转后的“列表反向迭代对象”和“排序后的列表”
lst = [4,3,5,7,6,5]
print(list(reversed(lst))) #打印[5, 6, 7, 5, 3, 4]
print(sorted(lst)) #打印[3, 4, 5, 5, 6, 7]
  • 注意:​sorted()返回一个列表reversed()返回一个类似zip的更神秘的可迭代对象,我们不必关心这个到底意味着什么,在for循环或join等方法中使用完全没问题。但是不能对它进行索引或切片操作,也不能对它调用列表方法。要想当作列表一样用的话,可以用list()对返回对象进行转换

4. 跳出循环

  • break(跳出循环)
#打印1~49
i = 1
while i<100:
if i == 50:#打印到50时跳出
break
print(i)
i += 1
  • continue(跳过本次循环)
#打印1 2 4 5
i = 1
while i <= 5:
if i == 3: #i==3时跳过
i += 1
continue
print(i)
i += 1

五、简单推导和字典推导

  • 推到不是语句,而是表达式
  • 列表推导是一种从其他列表创建列表的方法,类似集合推导,工作原理类似for循环
# 基本形式
>>> [x*x for x in range(10)]
[0,1,4,9,16,25,36,49,64,81,100]

# 增加一条if
>>>[x*x for x in range(10) if x % 3 == 0]
[0,9,36,81]

# 增加for
>>>[(x,y) for x in range(3) for y in range(4)]
[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]

# 也可同时加入更多的if和for
>>>[x*x for x in range(10) if x % 3 == 0 and x*x<10]
[0,9]

>>>[x*x for x in range(10) if x % 3 == 0 if x*x<10]#可以连写if代替复合条件
[0,9]
  • 将上面的​​[]​​换成​​()​不能实现元组推导,这样做将创建生成器
  • 可以用​​{}​​进行字典推导
>>> squares = {i:"{} squared is {}".format(i,i**2) for i in range(10)}
>>> squares[8]
'8 squared is 64'

六、其他语句del/pass/exec/eval

1. pass语句

  • pass语句不做任何事
  • pass可以用作占位符,因为python中的代码块不能为空,用pass填充代码块,可以让程序运行并测试已经写好的部分
flag = input()
if flag == '1':
print("...")
elif flag == '2': #分支没有写好,先跳过
pass
else:
print("xxx")
  • 也可以插入一个字符串用作占位符,这种做法尤其适合未完成的函数和类,因为这种字符串将充当文档字符串
def fibs(num):
'lalalala' # 文档字符串(这个字符串会被作为函数的一部分储存起来)
result = [0,1]
for i in range(num-2):
result.append(result[-2]+result[-1])
return result

print(fibs.__doc__) # 打印lalalala

2. exec语句

  • exec将字符串作为代码执行
>>> exec("print('Hello,world')")
Hello,world
  • 大多数情况下,还应该向它传递一个命名空间——用于存放变量的地方,否则将污染命名空间同名时覆盖原本代码中的变量或函数
>>> from math import sqrt
>>> scope = {} # 定义一个字典作为命名空间
>>> exec('sqrt = 1',scope) # exec的第二个参数指出命名空间,否则这里的sqrt会污染从math导入的import
>>> sqrt(4) # 导入的sqrt正常运行
2.0
>>> scope['sqrt'] # 指定命名空间scope,通过exec执行赋值语句创建的变量位于scope中
1
  • exec是一个过程,无返回值
  • 注意​​exec​可能引入不安全的代码

3. eval语句

  • eval计算用字符串表示的Python表达式值,并返回结果
# 创建一个python计算器
>>> eval(input("Enter an arithmetic expression:"))
  • 类似exec,也可以像eval提供命名空间

4. del语句

  • python中带有垃圾回收机制,如果一个对象没有任何人引用,将会被自动回收
>>> d = dict([('name','Tom') , ('age',18)]) 
>>> d = None #这时刚刚创建的字典将被释放空间
  • ​del​​语句也可以做到这一点,它不仅删除变量到对象的引用关系,还删除变量名称。但是del语句不会删除对象(事实上,python中无法手动释放对象,python的垃圾回收机制会自动释放不用的对象)
>>> x = [1,2,3]
>>> y = x
>>> del x
>>> y # 删除x后,对象没有消失,y仍然可引用;但若y也删除,列表对象被自动回收
[1,2,3]