第二章 Python 基础语法
1、Python 常用数据类型
- 在 Python 中变量不直接存储值,而是存储值的内存地址或者引用。
- 在 Python 中,不需要事先声明变量名及其类型,使用赋值语句可以直接创建任意类型的变量,变量的类型取决于等号右侧表达式的类型。
- 赋值(比如a=’ABC’)时,Python 解释器干了两件事:
1)在内存中创建一个 ‘ABC’ 的字符串
2)在内存中创建一个名为 a 的变量,并把它指向 ‘ABC’
2、Python 的核心数据类型
2.1 Number(数字)
Python支持int,float,complex三种不同的数字类型
a = 3
b = 3.14
c = 3+4j
print(type(a),type(b),type(c))
isinstance(a, int)
结果:
<class ‘int’> <class ‘float’> <class ‘complex’>
True
示例代码
import math
print(math.factorial(32)) # 计算32的阶乘
print(0.4-0.3 == 0.1) # 实数之间尽量避免直接比较大小
print(math.isclose(0.4-0.3, 0.1)) # 测试两个实数是否足够接近
c = 3+4j # Python内置支持复数及其运算
print(c+c) # 复数相加
print(c.real) # 查看复数的实部
print(c.imag) # 查看复数的虚部
print(3+4j.imag) # 相当于3+(4j).imag
结果:
263130836933693530167218012160000000
False
True
(6+8j)
3.0
4.0
7.0
2.2 String(字符串)
- Python 中的字符串可以使用单引号、双引号和三引号(三个单引号或三个双引号)括起来,使用反斜杠
\
转义特殊字符。 - Python3 源码文件默认以UTF-8编码,所有字符串都是 unicode 字符串
- 支持字符串拼接、截取等多种运算
a = "Hello"
b = "Python"
print("a+b 输出结果:", a+b)
print("a[1:4] 输出结果:", a[1:4])
结果:
a+b 输出结果: HelloPython
a[1:4] 输出结果: ell
示例代码
text = '''Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.'''
print(len(text)) # 字符串长度,即所有字符的数量
print(text.count('is')) # 字符串中单词is出现的次数
print('beautiful' in text) # 测试字符串中是否包含单词beautiful
print('='*20) # 字符串重复
print('Good'+'Morning') # 字符串连接
结果:
208
6
False====================
GoodMorning
2.3 List(列表)
- 列表可以完成大多数集合类的数据结构实现,列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。
- 列表是写在方括号
[]
之间,用逗号分隔开的元素列表。 - 列表索引值以
0
位开始值,-1
为从末尾的开始位置。 - 列表可以使用
+
操作符进行拼接,使用*
表示重复。
list = ['abcd', 786, 2.23, 'runoob', 70.2]
print(list[1:3])
tinylist = [123, 'runoob']
print(list + tinylist)
结果:
[786, 2.23]
[‘abcd’, 786, 2.23, ‘runoob’, 70.2, 123, ‘runoob’]
2.4 Tuple(元组)
- tuple 与 list 类似,不同之处在于tuple的元素不能修改。tuple 写在小括号里,元素之间用逗号隔开。
- 元组的元素不可变,但可以包含可变对象,如 list。
“注意: “ 定义一个只有一个元素的 tuple,必须加逗号
。t = ('abcd', 786, 2.23, 'runoob', 70.2) t1 = (1,) t2 = ('a','b',['A','B']) t[2][0] = 'X' t
结果:
(‘a’,’b’,[‘’,’B’])
2.5 dict(字典)
- 字典是无序的对象集合,使用键-值(key-value)存储,具有极快的查找速度。
- 键(key)必须使用不可变类型。
- 同一字典中,键(key)必须是唯一的。
d = {'Michael':95, 'Bob':75, 'Tracy':85}
d['Michael']
结果:
95
2.6 set(集合)
- set 和 dict 类似,也是一组 key 的集合,但不存储 value,由于 key 不能重复,所以,在 set 中,没有重复的 key.
- set是无序的,重复元素在 set 中自动被过滤。
s = set([1,2,3])
s
s = set([1,1,2,2,3,3])
s
结果:
{1, 2, 3}
{1, 2, 3}
注意:
set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集(&)、并集(|)、差集(-)等操作。
2.7 列表、元组、字典与集合综合示例代码
# 创建列表对象
x_list = [1,2,3]
# 创建元组对象
x_tuple = (1,2,3)
# 创建字典对象,元素形式为“键:值”
x_dict = {'a':97, 'b':98, 'c':99}
# 创建集合对象
x_set = {1,2,3}
# 使用下标访问列表中指定位置的元素,元素下标从0开始
print(x_list[1])
# 元组也支持使用序号作为下标,1表示第二个元素的下标
print(x_tuple[1])
# 访问字典中特定“键”对应的“值”,字典对象的下标是“键”
print(x_dict['a'])
# 查看列表长度,也就是其中元素的个数
print(len(x_list))
# 查看元素2在元组中首次出现的位置
print(x_tuple.index(2))
# 查看字典中哪些“键”对应的“值”为98
for key,value in x_dict.items():
if value == 98:
print(key)
# 查看集合中的元素的最大值
print(max(x_set))
结果:
2
2
97
3
1
b
3
3、运算符
3.1 算术运算符
以下假设变量 a 为10,变量 b 为21:
运算符 | 描述 | 实例 |
---|---|---|
+ | 加 - 两个对象相加 | a + b 输出结果31 |
- | 减 - 得到复数或是一个数减去另一个数 | a - b 输出结果-11 |
* | 乘 - 两个数相乘或是返回一个被重复若干次的字符串 | a * b 输出结果210 |
/ | 除 - x 除以 y | b / a 输出结果2.1 |
% | 取模 - 返回除法的余数 | b % a 输出结果1 |
** | 幂 - 返回x的y次幂 | a ** b 为10的21次方 |
// | 取整除 - 向下取接近除数的整数 | 9 // 2 结果是4 -9 // 2的结果是-5 |
要点:
+
运算符除了用于算术加法外,还可以用户列表、元组、字符串的连接。-
运算符除了用于整数、实数、复数之间的算术减法和相反数之外,还可以计算集合的差集。需要注意的是,在进行实数之间的运算时,有可能会出现误差。*
运算符除了表示整数、实数、复数之间的算术乘法,还可以用于列表、元组、字符串这几个类型的对象与整数的乘法,表示序列元素的重复,生成新的列表、元组或字符串。%
运算符可以用于求余运算,还可以用于字符串格式化。
算术运算符示例
# + 运算符除了用于算术加法外,还可以用于列表、元组、字符串的连接
print(3 + 5)
print(3.4 + 4.5)
print((3+4j) + (5+6j))
print('abc' + 'def')
print([1,2] + [3,4])
print((1,2) + (3,))
print("\n")
# - 运算符除了用于整数、实数、复数之间的算术减法和相反数之外,还可以计算集合的差集。
print(7.9 - 4.5) # 注意,结果有误差
print(5 -3)
num = 3
print(-num)
print(--num) # 注意,这里的--是两个负号,负负得正
print(-(-num)) # 与上一行代码含义相同
print({1,2,3} - {3,4,5}) # 计算差集
print({3,4,5} - {1,2,3})
print("\n")
结果:
8
7.9
(8+10j)
abcdef
[1, 2, 3, 4]
(1, 2, 3)
3.4000000000000004
2
-3
3
3
{1, 2}
{4, 5}
3.2 比较运算符
以下假设变量 a 为10,变量 b 为20:
运算符 | 描述 | 实例 |
---|---|---|
== | 等于 - 比较对象是否相等 | (a == b) 返回Fasle |
!= | 不等于 - 比较两个对象是否不相等 | (a != b) 返回True |
> | 大于 - 返回x是否大于y | (a > b) 返回Fasle |
< | 小于 - 返回x是否小于y。所有比较运算符返回1表示真,返回0表示假。这分别与特殊的变量True和False等价 | (a < b) 返回True |
>= | 大于等于 - 返回x是否大于等于y | (a >= b) 返回Fasle |
<= | 小于等于 - 返回x是否小于等于y | (a <= b) 返回True |
比较运算符示例
print(3+2 < 7+8) # 关系运算符优先级低于算术运算符
print(3 < 5 >2) # 等价于3<5 and 5>2
print(3 == 3 < 5) # 等价于3==3 and 3<5
print('12345' > '23456') # 第一个字符'1'<'2',直接得出结论
print('abcd' > 'Abcd') # 第一个字符'a'>'A',直接得出结论
print([85,92,73,84] < [91,82,73]) # 第一个数字85<91,直接得出结论
print([180,90,101] > [180, 90, 99]) # 前两个数字相等,第三个数字101>99
print({1,2,3,4} > {3,4,5}) # 第一个集合不是第二个集合的超集
print({1,2,3,4} <= {3,4,5}) # 第一个集合不是第二个集合的子集
print([1,2,3,4] > [1,2,3]) # 前三个元素相等,并且,第一个列表有多余的元素
结果:
True
True
True
False
True
True
True
False
False
True
3.3 赋值运算符
以下假设变量 a 为10,变量 b 为20:
运算符 | 描述 | 实例 |
---|---|---|
= | 简单的赋值运算符 | c = a + b 将 a + b 的运算结果赋值为c |
+= | 加法赋值运算符 | c += a 等效于 c = c + a |
-= | 减法赋值运算符 | c -= a 等效于 c = c - a |
*= | 乘法赋值运算符 | c *= a 等效于 c = c * a |
/= | 除法赋值运算符 | c /= a 等效于 c = c / a |
%= | 取模赋值运算符 | c %= a 等效于 c = c % a |
**= |
幂赋值运算符 | c **= a 等效于 c = c ** a |
//= | 取整除赋值运算符 | c //= a 等效于 c = c // a |
3.4 逻辑运算符
以下假设变量 a 为10,变量 b 为20:
运算符 | 描述 | 实例 |
---|---|---|
and | 布尔“与” - 如果x为False,x and y 返回Fasle,否则它返回y的计算值 | (a and b) 返回20 |
or | 布尔“或” - 如果x为True,它返回x的值,否则它返回y的计算值 | (a or b) 返回20 |
not | 布尔“非” - 如果x为True,返回Fasle,如果x为False,它返回True | not(a and b) 返回False |
逻辑运算符示例
print(3 in range(5) and 'abc' in 'abcdefg')
print(3-3 or 5-2)
print(not 5)
print(not [])
结果:
True
3
False
True
3.5 成员运算符
运算符 | 描述 | 实例 |
---|---|---|
in | 如果在指定的序列中找到值返回True,否则返回Fasle | x在y序列中,如果x在y序列中返回True |
not in | 如果在指定的序列中没有找到值返回True,否则返回False | x不在y序列中,如果x不在y序列中返回True |
成员运算符示例
print(60 in [70, 60, 50, 80] )
print('abc' in 'a1b2c3dfg')
print([3] in [[3], [4], [5]])
print('3' in map(str, range(5)))
print(5 in range(5))
结果:
True
False
True
True
False
3.6 身份运算符
运算符 | 描述 | 实例 |
---|---|---|
is | is 是判断两个标识符是不是引用一个对象 | x is y, 类似id(x) == id(y),如果引用的是同一个对象则返回True,否则返回False |
is not | is not 是判断两个标识符是不是引用自不同对象 | x is not y,类似id(a)!=id(b)。如果引用的不是同一个对象则,返回结果True,否则返回False |
注意
:id(x)
函数用于获取对象内存地址
特别的
:is
与 ==
区别:is
用于判断两个变量引用对象是否为同一个,==
用于判断引用变量的值是否相等。
身份运算符示例
a = 20
b = 20
if (a is b):
print("1 : a 和 b 有相同的标识")
else:
print("1 : a 和 b 没有相同的标识")
print(id(a))
print(id(b))
# 修改变量b的值
b = 30
if(a is b):
print("3 : a 和 b 有相同的标识")
else:
print("3 : a 和 b 没有相同的标识")
print(id(a))
print(id(b))
# is 与 == 的区别
a = [1, 2, 3]
b = [1, 2, 3]
print(b == a)
print(b is a)
print(id(a))
print(id(b))
结果:
1 : a 和 b 有相同的标识
140715597430912
140715597430912
3 : a 和 b 没有相同的标识
140715597430912
140715597431232
True
False
1500602520840
1500602814024
运算符优先级示例
a = 20
b = 10
c = 15
d = 5
e = 0
e = (a + b) * c / d # (30 * 15) / 5
print("(a + b) * c / d 运算结果为:", e)
e = ((a + b) * c) / d # (30 * 15) / 5
print("((a + b) * c) / d 运算结果为:", e)
e = (a + b) * (c / d) # (30) * (15/5)
print("(a + b) * (c / d) 运算结果为:", e)
e = a + (b * c) / d # 20 + (150/5)
print("a + (b * c) / d 运算结果为:", e)
结果:
(a + b) * c / d 运算结果为: 90.0
((a + b) * c) / d 运算结果为: 90.0
(a + b) * (c / d) 运算结果为: 90.0
a + (b * c) / d 运算结果为: 50.0
4、列表
4.1 列表的基本概念
- 列表是有序的元素集合,所有元素放在一对
中括号
中,用逗号
隔开,没有长度限制。 - 列表索引值以
0
为开始值,-1
为从末尾的开始位置。 - 列表可以使用
+
操作符进行拼接,使用*
表示重复。 - 当列表元素增加或删除时,列表对象自动进行扩展或收缩內存,保证元素之间没有缝隙。
列表元素可以通过索引访问单个元素
a=[4, 2, 3, 6, 6, 9, 5, 8, 1]
a[3]=6
a[0]=4
a9]=异常
列表
- 列表可以完成大多数集合类的数据结构实现。
- 列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套)。
列表元素修改
- 列表大小没有限制,可以随时修改。
- 列表元素变可随时修改。
a=[4, 2, 3, 6, 6, 9, 5, 8, 1]
a.insert(0, 1)
print(a)
a[0]=10
print(a)
结果:
[1, 4, 2, 3, 6, 6, 9, 5, 8, 1]
[10, 4, 2, 3, 6, 6, 9, 5, 8, 1]
4.2 列表的基本操作
列表操作符 | 操作符含义 |
---|---|
<list1> + <list2> |
连接两个列表 |
<list> * <整数类型> |
对列表进行整数次重复 |
<list> [<整数类型> ] |
索引列表中的元素 |
len(<seq> ) |
列表中元素个数 |
<list> [<整数类型> :<整数类型> ] |
取列表的一个子序列 |
for <var> in <list> |
对列表进行循环列举 |
<expr> in <list> |
成员检查,判断<expr> 是否在列表中 |
4.3 列表相关方法
方法 | 方法含义 |
---|---|
<list> .append(x) |
将元素x 增加到列表的最后 |
<list> .sort() |
将列表元素排序 |
<list> .reverse() |
将序列元素反转 |
<list> .index(x) |
返回第一次出现元素x 的索引值 |
<list> .insert(i,x) |
在i 位置处插入新元素x |
<list> .count(x) |
返回元素x 在列表中的数量 |
<list> .remove(x) |
删除列表中第一次出现的元素x |
<list> .pop(i) |
取出列表中位置i 的元素,并删除它 |
4.4 创建列表
>>> list((3,5,7,9,11)) # 将元组转换为列表
[3,5,7,9,11]
>>> list(range(1, 10, 2) # 将range对象转换为列表
[1, 3, 5, 7, 9]
>>> list('hello world') # 将字符串转换为列表,每个字符转换为列中的一个元素
['h','e','l','l','o','w','o','r','l','d']
>>> list({3,7,5}) # 将集合转换为列表,集合中的元素是无序的
[3, 5, 7]
>>> x = list() # 创建空列表
>>> x = [1, 2, 3]
>>> del x # 删除列表对象
>>> x # 对象删除后无法再访问,抛出异常
NameError: name 'x' is not defined
4.5 利用索引访问列表
data = list(range(10))
print(data)
print(data[0]) # 第一个元素的下标为0
print(data[1]) # 第二个元素的下标为1
print(data[-1]) # -1表示最后一个元素的下标
print(data[15]) # 15不是有效下标,代码抛出异常
结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
0
1
9
Traceback (most recent call last):
File "C:\Users\xz\.spyder-py3\temp.py", line 12, in <module>
print(data[15]) # 15不是有效下标,代码抛出异常
IndexError: list index out of range
4.6 列表常用方法
append()、insert()、 extend()
list = [1,2,3,4]
print(list)
list. append(5)
print(list)
list.insert(0, 0)
print(list)
list.insert(2, 1.5)
print(list)
list.extend([6, 7])
print(list)
结果:
[1, 2, 3, 4]
[1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5]
[0, 1, 1.5, 2, 3, 4, 5]
[0, 1, 1.5, 2, 3, 4, 5, 6, 7]
pop()、remove()
list = [1, 2, 3, 4, 5, 6]
print(list.pop()) # 删除并返回最后一个元素
print(list)
print(list.pop(0)) # 删除并返回下标为0的元素,后面的元素向前移动
print(list)
print(list.pop(2)) # 删除并返回下标为2的元素,后面的元素向前移动
print(list)
list = [1, 2, 3, 2, 4, 2]
list.remove(2) # 删除第一个2, 该方法没有返回值
print(list)
结果:
6
[1, 2, 3, 4, 5]
1
[2, 3, 4, 5]
4
[2, 3, 5]
[1, 3, 2, 4, 2]
sort()、reverse()
from random import sample
# 在range(10000) 中任选10个不重复的随机数
data = sample(range(10000), 10)
print(data)
data.reverse() # 翻转,首尾交换,该方法没有返回值
print(data)
data.sort() # 按元素大小进行排序,该方法没有返回值
print(data)
data.sort(key=str) # 按所有元素转换为字符串后的大小进行排序
print(data)
结果:
[1680, 5901, 5733, 45, 8628, 5475, 3446, 4598, 555, 9934]
[9934, 555, 4598, 3446, 5475, 8628, 45, 5733, 5901, 1680]
[45, 555, 1680, 3446, 4598, 5475, 5733, 5901, 8628, 9934]
[1680, 3446, 45, 4598, 5475, 555, 5733, 5901, 8628, 9934]
count()、index()
list = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
print(list.count(2)) # 输出2
print(list)
print(list.index(4)) # 输出6
print(list)
print(list.index(5)) # 代码抛出异常,提示5 is not in list
结果:
2
[1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
6
[1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
---------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-28-36d2725a5d78> in <module>
4 print(list.index(4)) # 输出6
5 print(list)
----> 6 print(list.index(5)) # 代码抛出异常,提示5 is not in list
ValueError: 5 is not in list
4.7 列表推导式
data = [2**i for i in range(64)]
等价于
data = []
for i in range(64):
data.append(2**i)
data = [num for num in range(20) if num%2==1]
等价于
data = []
for num in range(20):
if num%2 == 1:
data.append(num)
5、元组
5.1 基本概念
元组(tuple)是包含多个元素的类型,元素之间用逗号分割。
如:t1 = (123, 456, “hello”)可以通过把若干元素放在一对圆括号中创建元组,如果只有一个元素的话则需要多加一个逗号,例如(3,)
也可以使用tuple()函数把列表、字典、集合、字符串以及range对象、map对象、zip对象或其他类似对象转换为元组。
元组可以是空的,t2=()
一个元组也可以作为另一个元组的元素,此时,作为元素的元组需要增加括号,从而避免歧义,如:t3 = (123, 456, (“hello”, “world”))
元组中各元素存在先后关系,可以通过索引访问元组中的元素。
例如:t3[0]元组定义后不能更改,也不能删除。
t3[0] = 789与字符串类型类似,可以通过索引区来访问元组中的部分元素。
例如:t3[1:]与字符串一样,元组之间可以用
+
号和*
号进行运算
5.2 元组与列表的区别
元组是
不可变
的,不能直接修改元组中元素的值,也不能为元组增加或删除元素。因此,元组没有提供 append()、 extend()和insert()等方法,也没有 remove()和pop()方法。元组的访问速度比列表
更快,开销更小
。如果定义了一系列常量值,主要用途只是对它们进行遍历或其他类似操作,那么一般建议使用元组而不用列表。元组可以使得
代码更加安全
。例如,调用函数时使用元组传递参数可以防止在函数中修改元组,而使用列表则无法保证这一点。元组可用作字典的键,也可以作为集合的元素,但列表不可以,包含列表的元组也不可以。
5.3 生成器表达式
gen = (2**i for i in range(8)) # 创建生成器对象
print(gen)
print(list(gen)) # 转换为列表,用完了生成器对象中的所有元素
print(tuple(gen)) # 转换为元组,得到空元组
gen = (2**i for i in range(8)) # 重新创建生成器对象
print(next(gen)) # 使用next()函数访问下一个元素
print(next(gen))
for item in gen: # 使用for循环访问剩余的所有元素
print(item, end=' ')
<generator object <genexpr> at 0x0000015D62F32138>
(1, 2, 4, 8, 16, 32, 64, 128)
()
1
2
4 8 16 32 64 128
6、切片操作
适用于列表和元组
切片是用来获取列表、元组、字符串等有序序列中部分元素的一种语法。在形式上,切片使用2个冒号分割的3个数字来完成。
[start:end:step]
其中第一个数字
start
表示切片开始位置,默认为0;第二个数字end
表示切片截止(但不包含)位置(默认为列表长度);第三个数字step
表示切片的步长(默认为1),省略步长时还可以同时省略最后一个冒号。当step为
负整数
时,表示反向切片,这时start应该在end的右侧。
data = list(range(20))
print(data[:]) # 获取所有元素的副本
print(data[:3]) # 前三个元素
print(data[3:]) # 下标3之后的所有元素
print(data[::3]) # 每3个元素选取1个
print(data[-3:]) # 最后3个元素
print(data[:-5]) # 除最后5个元素之外的所有元素
结果:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[0, 1, 2]
[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[0, 3, 6, 9, 12, 15, 18]
[17, 18, 19]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
7、字典
7.1 基本概念
- 字典是
无序
的对象集合,使用键-值(key- value)存储,具有极快的查找速度。 - 键(key)必须使用不可变类型
- 同一个字典中,键(key)必须是唯一的
- 字典的每个键值key=>value对用冒号:分割,每个键值对之间用逗号,分割,整个字典包括在花括号{}中,格式如下所示
dic = {key1: value1, key2: value2)
>>> d={'Michael':95, 'Bob':75, 'Tracy':85}
>>> d['Michael']
95
7.2 常用方法
方法 | 描述 |
---|---|
keys() | 返回字典中键的列表 |
values() | 返回字典中值的列表 |
items() | 返回tuples的列表。每个tuple由字典的键和相应值组成 |
clear() | 删除字典的所有条目 |
copy() | 返回字典高层结构的一个拷贝,但不复制嵌入结构,而只复制对那些结构的引用 |
update(x) | 用字典x中的键值对更新字典内容 |
get(x[,y]) | 返回键x,若未找到该键返回none,若提供y,则未找到x时返回y |
字典键一般是唯一
的,如果重复最后的一个键值
对会替换前面的
,值不需要唯一
。
dict = {'a':1, 'b':2, 'b':'3'}
dict['b']
dict
jupyter一行一行运行结果:
‘3’
{‘a’: 1, ‘b’: ‘3’}
7.3 创建字典:基础语法方式
- 字典中值
可以取任何数据类型
,但键必须是不可变
的,如字符串
,数字
或元组
。如
dict={‘Alice’: ‘2341’, ‘Beth’: ‘9102’, ‘Cecil’: ‘3258’} - 也可如此创建字典,如
dict1={‘abc’: 456}
dict2={‘abc’: 123, 98.6: 37}
7.4 创建字典:dict函数
- 使用dict函数,通过其他映射(比如字典)或者(键,值)序列对创建字典
items = [('name', 'Gumby'),('age', 42)]
d= dict(items)
print(d)
结果:
{‘name’: ‘Gumby’, ‘age’: 42}
- dict函数也可以通过关键字参数来创建字典
d = dict(name='Gumby', age=42)
print(d)
结果:
{‘name’: ‘Gumby’, ‘age’: 42}
7.5 字典元素访问
data = dict(name='张三', age=18, sex='M')
print(data['name']) # 使用“键”作为下标,访问“值”
print(data.get('age'))
print(data.get('address', '不存在这个键')) # “键”不存在,返回默认值
print(list(data)) # 把所有的“键”转换为列表
print(list(data.values())) # 把所有的“值”转换为列表
print(list(data.items())) # 把所有的元素转换为列表
for key,value in data.items(): # 遍历字典的“键:值”元素
print(key, value, sep='\t')
结果:
张三
18
不存在这个键
[‘name’, ‘age’, ‘sex’]
[‘张三’, 18, ‘M’]
[(‘name’, ‘张三’), (‘age’, 18), (‘sex’, ‘M’)]
name 张三
age 18
sex M
7.6 字典元素修改、添加与删除
- 当以指定“键”为下标为字典元素赋值时,有两种含义:
1)若该“键”存在,表示修改该“键”对应的值。
2)若不存在,表示添加一个新元素。sock = {'IP': '127.0.0.1', 'port': 80} sock['port'] = 8080 # 修改已有元素的“值” sock['protocol'] = 'TCP' # 增加新元素 print(sock)
结果:
{‘IP’: ‘127.0.0.1’, ‘port’: 8080, ‘protocol’: ‘TCP’}
- 使用字典对象的update()方法可以将另一个字典的元素一次性全部添加到当前字典对象,如果两个字典中存在相同的“键”,则以另一个字典中的“值”为准对当前字典进行更新。
sock = {'IP': '127.0.0.1', 'port': 80}
# 更新了一个元素的“值”,增加了一个新元素
sock.update({'IP': '192.168.9.62', 'protocol': 'TCP'})
print(sock)
结果:
{‘IP’: ‘192.168.9.62’, ‘port’: 80, ‘protocol’: ‘TCP’}
- 可以使用字典对象的pop()删除指定“键”对应的元素,同时返回对应的“值”。
- popitem()方法用于删除字典的一个键对,并返回一个包含两个元素的元组,其中的两个元素分别是字典元素的“键”和“值”。
- 也可以使用del删除指定的“键”对应的元素。
sock = {'IP':'192.168.9.62','port':80,'protocol':'TCP'}
print(sock.pop('IP')) # 朋除并返回指定键的元素
print(sock.popitem()) # 删除并返回一个元素
del sock['port'] # 朋除指定键的元素
print(sock)
结果:
192.168.9.62
(‘protocol’, ‘TCP’)
{}
8、集合
8.1 概述
- Python集合是
无序
、可变
的容器对象,所有元素放在一对大括号
中,元素之间使用逗号分隔,同一个集合内的每个元素都是唯一
的,不允许重复
。 - 集合中只能包含
数字、字符串、元组
等不可变类型的数据,而不能包含列表、字典、集合
等可变类型的数据,包含列表等可变类型数据的元组也不能作为集合的元素。 - 集合中的元素是
无序
的,元素存储顺序和添加顺序并不一致。 - 集合不支持使用下标直接访问特定位置上的元素,也不支持使用 random中的 choice()函数从集合中随机选取元素,但支持使用 random模块中的 sample函数随机选取部分元素。
8.2 set(集合)
- set和dict类似,也是一组key的集合,但不存储value,由于key不能重复,所以,在set中,没有重复的key。
- set是无序的,重复元素在set中自动被过滤。
s = set([1,2,3])
s
s = set([1,1,2,2,3,3])
s
jupyter一行一行运行结果:
{1, 2, 3}
{1, 2, 3}
注意;
set可以看成数学意义上的无序和无重复元素的集合,因此,两个set可以做数学意义上的交集(&)、并集(|)、差集(-)等操作。
8.3 集合常用方法
- s = add(x):将元素x添加到集合s中,如果元素已存在,则不进行任何操作。
- s = update(x):将x的元素添加到集合s中,x可以是列表、元组、字典等。
data = {30, 40, 50}
data.add(20) # 增加新元素20
print(data)
data.add(50) # 集合中已包含50,忽略本次操作
print(data)
data.update({40, 60}) # 忽略40,增加新元素60
print(data)
结果:
{40, 50, 20, 30}
{40, 50, 20, 30}
{50, 20, 40, 60, 30}
- s.pop(x):随机删除集合中的一个元素。
- s.remove(x):将元素x从集合s中移除,如果元素不存在,则会发生错误。
- s.discard(x):将元素x从集合s中移除,如果元素不存在,
不会发生错误
。
data = {30, 40, 50}
data.remove(30) # 删除元素30
print(data)
data.discard(30) # 集合中没有30,忽略本次操作
print(data.pop()) # 删除并返回集合中的一个元素
print(data)
结果:
{40, 50}
40
{50}
9、字符串
9.1 概述
- 字符串(str)是用双引号””或者单引号’’括起来的一个或多个字符。
- 字符串可以保存在变量中,也可以单独存在。
- 字符串属于不可变对象,所有方法都是返回处理后的字符串或字节串,不对原字符串进行任何修改。
- 可以用type()函数测试一个字符串的类型。
In[1]: type("1")
Out[1]: str
In[2]: type(1)
Out[2]: int
- 字符串是一个字符序列:字符串最左端位置标记为0,依次增加。字符串中的编号叫做”索引”。
H | e | l | l | o | J | a | c | k | |
---|---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
9.2 转义
- Python语言转义符:
\
,在字符串中表示转义,即该字符与后面相邻的一个字符共同组,成了新的含义。 - 输出带有引号的字符串,可以使用转义符。
- 使用
\\
输出带有转义符的字符串。
print(“"你好"“)
print(“\\
“) - 用转义符可以在字符串中表达一些不可直接打印的信息,例如:用
\n
表示换行;\t
表示制表符。
print(“Hello\nWorld\n\nGoodbye\t32”)
9.3 字符串操作
- 单个索引辅助访问字符串中的特定位置,格式为
<string>[<索引>]
。
str1 = “hello, world”
print(str1[1]) - Python中字符串索引
从0开始
,一个长度为L的字符串最后一个字符的L-1
。 - Python同时允许使用负数从字符串右边末尾位置是向左边进行反向索引,
最右侧索引 值是-1
。 - 可以通过两个索引值确定一个位置范围,返回这个范围的子串,字符串的切片。
格式:< string>[< start>:<end>]
- start和end都是整数型数值,这个子序列从索引 start开始直到索引end结束,但不包括end位置。
- 字符串之间可以通过
+或*
进行连接。
加法操作(+)将两个字符串连接
成为一个新的字符串。
乘法操作()生成一个由其本身字符串重复连接
而成的字符串。
x in s:如果x是s的子串,返回True,否则返回 False。
str[N:M]:切片,返回子串。 - len()函数能返回一个字符串的长度。
str1 = “hello, world”
len(str1) - 大多数数据类型都可以通过
str()
函数转换为字符串:如str(123)。 - type函数测试一个字符串的类型。
9.4 字符串遍历操作
可以通过for和in组成的循环来遍历字符串中每个字符
for <var> in <string>:
操作
str1 = "Hello, world"
for p in str1:
print(p)
结果:
H
e
l
l
o
,
w
o
r
l
d
9.5 字符串处理方法
操作 | 含义 |
---|---|
+ | 连接 |
* | 重复 |
<string> [] |
索引 |
<string> [:] |
剪切 |
len(<sting> ) |
长度 |
<sting> .upper() |
字符串中字母大写 |
<sting> .lower() |
字符串中字母小写 |
<sting> 。strip() |
去两边空格及去指定字符串 |
<sting> .split() |
按指定字符分割字符串为数组 |
<sting> .join() |
连接两个字符串序列 |
<sting> .find() |
搜索指定字符串 |
<sting> .replace() |
字符串替换 |
for <var> in <string> |
字符串迭代 |
9.6 常用方法
- Index(x)、rindex(0):检测是否包含在字符串中,返回相应的索引值,如果不存在,返回异常。
- count(x):返回str在string里面出现的次数。
text = '处处飞花飞处处,声声笑语笑声声。'
print(text.rindex('处'))
print(text.index('声'))
print(text.count('处'))
结果:
6
8
4
- replace(str1, str2, [,max]):把将字符串中的str1替换成str2,如果max指定,则替换不超过max次。
text = "Python是一门非常棒的编程语言。"
# replace()方法返回替换后的新字符申,可以直接再次调用replace()方法
print(text.replace('棒', '优雅').replace('编程', '程序设计'))
print(text)
结果:
Python是一门非常优雅的程序设计语言。
Python是一门非常棒的编程语言。
- maketrans():创建字符映射的转换表。
- translate(str):根据str给出的映射转换表转换string字符。
table = ''.maketrans('0123456789', '零一二三四伍陆柒捌玖')
print('Tel:62819743'.translate(table))
结果:
Tel:陆二捌一玖柒四三
- ljust(width[,fillchar]):返回一个原字符串左对齐,并使用fillchar填充至长度width的新字符串,fillchar默认为空格。rjust()、center()类似。
print('居左'.ljust(20)+'结束')
print('居右'.rjust(20, '#')) # 左侧使用并号填充
print('居中'.center(20, '=')) # 两侧使用等号填充
结果:
居左 结束
##################居右
=========居中=========
- split(str= “”, num=string.count(str)),其中num=string.count(str)以str为分隔符截取字符串,如果num有指定值,则仅截取num+1个子字符串。rsplit()类似,从右侧开始截取。
- join(seq):以指定字符串作为分隔符,将seq中所有的元素(的字符串表示)合并为一个新的字符串。
text = 'Beautiful is better than ugly.'
print(text.split()) # 使用空白字符进行分隔
print(text.split(maxsplit=1)) # 最多分隔一次
print(text.rsplit(maxsplit=2)) # 最多分隔两侧
print('1,2,3,4'.split(',')) # 使用逗号作为分隔符
print(','.join(['1', '2', '3', '4'])) # 使用逗号作为连接符
print(':'.join(map(str, range(1, 5)))) # 使用冒号作为连接符
print(''.join(map(str, range(1, 5)))) # 直接连接,不插入任何连接符
结果:
[‘Beautiful’, ‘is’, ‘better’, ‘than’, ‘ugly.’]
[‘Beautiful’, ‘is better than ugly.’]
[‘Beautiful is better’, ‘than’, ‘ugly.’]
[‘1’, ‘2’, ‘3’, ‘4’]
1,2,3,4
1:2:3:4
1234
- lower()、upper()、capitalize()(句子首个单词大写)、title()(每个单词大写)、swapcase()(小写和大写相互转换)。
text = 'Simple is better than complex.'
print(text.lower())
print(text.upper())
print(text.capitalize())
print(text.title())
print(text.swapcase())
结果:
simple is better than complex.
SIMPLE IS BETTER THAN COMPLEX.
Simple is better than complex.
Simple Is Better Than Complex.
sIMPLE IS BETTER THAN COMPLEX.
- startswith()、endswith():检查字符串是否是以指定子字符串substr开头或结束,是则返回True。
text = 'Simple is better than complex.'
print(text.startswith('simple'))
print(text.startswith('Simple'))
print(text.endswith(('.', '!', '?')))
结果:
False
True
True
- strip()、rstrip()、lstrip():截取字符串的指定字符。
text = ' ======test===##### '
print(text.strip()) # 删除两侧的空白字符
print(text.strip('=# ')) # 删除两侧的=、#和空格
结果:
======test===#####
test
10、程序控制流
10.1 程序基本结构
- 顺序结构是程序的基础,但单一的顺序结构不可能解决所有问题。
- 程序由三种基本结构组成:
顺序结构
分支结构
循环结构 - 任何算法(程序)都可以由这三种基本结构组合来实现。
10.1.1 顺序结构
程序按线性顺序依次执行
↓
<语句块1>
↓
<语句块2>
10.1.2 分支结构
程序根据条件判断结果而选择不同执行路径
有单分支和二分支结构,二分支结构可组合成多分支结构
10.1.3 循环结构
程序根据条件判断结果向后反复执行
根据循环体触发条件不同,包括条件循环和遍历循环结构
10.2 分支结构(单分支、二分支、多分支)
10.2.1 单分支结构:if语句
if 语句语法格式
if <条件>:
语句块
- 语句块是
if条件满足
后执行的一个或多个语句序列,语句块中语句通过与 if 所在行形成缩进
表达包含关系。 - if 语句首先评估<条件>的结果值,如果结果为True,则执行语句块里的语句序列,然后控制转向程序的下一条语句。
- 如果结果为 False,语句块里的语句会被跳过。
单分支结构示例
题目:生成包含两个或三个汉字的人名。
from random import choice, random
name = choice('董孙李周赵钱王')
condition = random()
if condition>0.5: # random()函数返回[0,1)区间上的随机数
name += choice('付玉延邵子凯')
name += choice('国楠栋涵雪玲瑞')
print(condition)
print(name)
结果:
0.05645875733667094
钱国
10.2.2 二分支结构:if-else语句
- if-else 语句语法格式
if <条件>:
<语句块1>
else:
<语句块2>
- <语句块1>是在 if 条件满足后执行的一个或多个语句序列
- <语句块2>是if条件不满足后执行的语句序列
二分支结构示例
题目:PM2.5空气质量提醒。
PM = eval(input("请输入PM2.5数值:"))
if PM >= 75:
print("空气存在污染,请小心!")
else:
print("空气没有污染,可以展开户外活动!")
结果:
请输入PM2.5数值:98
空气存在污染,请小心!
10.2.3 二分支结构简洁表达方式
- 适合通过判断返回特定值,语法格式:
<表达式1> if <条件> else <表达式2>
PM = eval(input("请输入PM2.5数值:"))
print("空气存在污染,请小心!") if PM >= 75 else print("空气没有污染,可以展开户外活动!")
结果:
请输入PM2.5数值:98
空气存在污染,请小心!
请输入PM2.5数值:50
空气没有污染,可以展开户外活动!
- 这种紧凑结构适合对特殊值进行处理的情况
10.2.4 多分支结:if-elif-else语句
if-elif-else语句语法格式
if <条件1>:
<语句块1>
elif <条件2>:
<语句块2>
...
else:
<语句块N>
- 多分支结构是二分支结构的扩展。
- 通常用于设置同一判断条件的多条执行路径。
- 运行时依次评估寻找第一个结果为 True 的条件,执行该条件下的语句块,结束后跳过整个多分支结构,执行后面的语句。
- 如果没有任何条件成立,则执行 else 下的语句块。
- else 语句是可选的,不一定要有。
多分支结构示例
题目:PM2.5空气质量(分级)提醒。
PM = eval(input("请输入PM2.5数值:"))
if 0 <= PM < 35:
print("空气优质,快去户外运动!")
elif 35 <= PM < 75:
print("空气良好,适度户外运动!")
else:
print("空气污染,请小心!")
请输入PM2.5数值:24
空气优质,快去户外运动!
10.3 循环结构(for循环、while循环)
10.3.1 for 循环
- Python 可以使用 for 语句循环遍历整个序列的值。
- for 循环中,循环变量 var 遍历队列中每一个值,循环的语句体为每个 var 值执行一次。
for <var> in <sequence>:
<body>
- for 循环在执行过程中,直接在序列上进行遍历,而非在内存中生成一个新的序列拷贝进行遍历。
for 循环结构示例
题目:输入N个数,求平均数。
#average
n = eval(input("How many numbers? "))
sum = 0.0
for i in range(n):
x = eval(input("Enter a number>>"))
sum += x
print("\nThe average is: ", sum / n)
结果:
How many numbers? 4
Enter a number>>12
Enter a number>>3
Enter a number>>4
Enter a number>>24
The average is: 10.75
- for 循环非常适合用来遍历容器类对象(列表、元组、字典、集合、字符串以及map、zip等类似对象)中的元素,语法形式为:
for 循环遍历 in 容器类对象:
循环体
else:
[else语句代码块]
- range() 函数可创建一个整数列表,用 for 语句进行循环
for i in range (10)
- for 循环缺点
1)程序开始时必须提供输入数字总数。
2)大规模数字求平均值需要用户先数清楚个数。
3)for 循环是需要提供固定循环次数的循环方式。
10.3.2 while 循环语法
while 条件表达式:
循环体
else:
[else 语句代码块]
while 循环
,只要条件满足,就不断循环,条件不满足时退出循环。
在while … else 在条件语句为 false 时执行 else 的语句块
sum = 0
n =99
while n > 0:
sum = sum +n
n = n-2
print(sum)
结果:
2500
count = 0
while count < 3:
print(count, "小于 3")
count = count + 1
else:
print(count, "大于或等于 3")
结果:
0 小于 3
1 小于 3
2 小于 3
3 大于或等于 3
while循环结构示例
# 比较复杂一点的有嵌套的while语句
a = 1
while a < 8:
if a <= 4:
print(a)
else:
print("hello")
a = a + 1
else:
print("test")
结果:
1
2
3
4
hello
hello
hello
test
10.3.3 循环保留字(break、continue)
- 循环保留字:break
1)break用来跳出最内层 for 或 while 循环,脱离该循环后程序从循环后代码继续执行。
2)break语句跳出了最内层 while 循环,但仍然继续执行外层循环。每个 break语句只有能
力跳出当前层次循环。 - 循环保留字:continue
1)continue 结束当前当次循环,即跳出循环体中下面尚未执行的语句,但不跳出当前循环。
2)对于 while 循环,继续求解循环条件。而对于 for 循环,程序流程接着遍历循环列表。
3)区别:continue 语句只结束本次循环,而不终止整个循环的执行。而 break 语句则是结 束整个循环过程,不再判断执行循环的条件是否成立
。
for循环结构break保留字示例
for letter in 'Runoob': # 第一个实例
if letter == 'o':
break
print("当前字母为:", letter)
var = 10 # 第二个实例
while var > 0:
print("当前变量值为:", var)
var = var - 1
if var == 7:
break
print("Good bye!")
结果:
当前字母为: R
当前字母为: u
当前字母为: n
当前变量值为: 10
当前变量值为: 9
当前变量值为: 8
Good bye!
for循环结构continue保留字示例
题目:编写程序,输出各位数字都不相同的所有三位数。
digits = range(10)
for i in digits: # 选择第一个数字
if i == 0:
continue # 第一位数不能是0
for j in digits:
if j == i:
continue # 第二位与第一位相同,则忽略后面的操作
for k in digits:
if k in (i,j):
continue # 三位数字必须互不相同
print(int(str(i)+str(j)+str(k)), end=' ')
结果:
102 103 104 105 106 107 108 109 120 123 124 125 126 127 128 129 130 132 134 135 136 137 138 139 140 142 143 145 146 147 148 149 150 152 153 154 156 157 158 159 160 162 163 164 165 167 168 169 170 172 173 174 175 176 178 179 180 182 183 184 185 186 187 189 190 192 193 194 195 196 197 198 201 203 204 205 206 207 208 209 210 213 214 215 216 217 218 219 230 231 234 235 236 237 238 239 240 241 243 245 246 247 248 249 250 251 253 254 256 257 258 259 260 261 263 264 265 267 268 269 270 271 273 274 275 276 278 279 280 281 283 284 285 286 287 289 290 291 293 294 295 296 297 298 301 302 304 305 306 307 308 309 310 312 314 315 316 317 318 319 320 321 324 325 326 327 328 329 340 341 342 345 346 347 348 349 350 351 352 354 356 357 358 359 360 361 362 364 365 367 368 369 370 371 372 374 375 376 378 379 380 381 382 384 385 386 387 389 390 391 392 394 395 396 397 398 401 402 403 405 406 407 408 409 410 412 413 415 416 417 418 419 420 421 423 425 426 427 428 429 430 431 432 435 436 437 438 439 450 451 452 453 456 457 458 459 460 461 462 463 465 467 468 469 470 471 472 473 475 476 478 479 480 481 482 483 485 486 487 489 490 491 492 493 495 496 497 498 501 502 503 504 506 507 508 509 510 512 513 514 516 517 518 519 520 521 523 524 526 527 528 529 530 531 532 534 536 537 538 539 540 541 542 543 546 547 548 549 560 561 562 563 564 567 568 569 570 571 572 573 574 576 578 579 580 581 582 583 584 586 587 589 590 591 592 593 594 596 597 598 601 602 603 604 605 607 608 609 610 612 613 614 615 617 618 619 620 621 623 624 625 627 628 629 630 631 632 634 635 637 638 639 640 641 642 643 645 647 648 649 650 651 652 653 654 657 658 659 670 671 672 673 674 675 678 679 680 681 682 683 684 685 687 689 690 691 692 693 694 695 697 698 701 702 703 704 705 706 708 709 710 712 713 714 715 716 718 719 720 721 723 724 725 726 728 729 730 731 732 734 735 736 738 739 740 741 742 743 745 746 748 749 750 751 752 753 754 756 758 759 760 761 762 763 764 765 768 769 780 781 782 783 784 785 786 789 790 791 792 793 794 795 796 798 801 802 803 804 805 806 807 809 810 812 813 814 815 816 817 819 820 821 823 824 825 826 827 829 830 831 832 834 835 836 837 839 840 841 842 843 845 846 847 849 850 851 852 853 854 856 857 859 860 861 862 863 864 865 867 869 870 871 872 873 874 875 876 879 890 891 892 893 894 895 896 897 901 902 903 904 905 906 907 908 910 912 913 914 915 916 917 918 920 921 923 924 925 926 927 928 930 931 932 934 935 936 937 938 940 941 942 943 945 946 947 948 950 951 952 953 954 956 957 958 960 961 962 963 964 965 967 968 970 971 972 973 974 975 976 978 980 981 982 983 984 985 986 987
11、函数
11.1 基本概念
- 函数是一段具有特定功能的、
可重用
的语句组,通过函数名进行功能调用。 - 函数也可以看作是一段具有名字的
子程序
,可以在需要的地方调用执行,不需要在每个执行地方重复编写这些语句。 - 每次使用函数可以提供不同的参数作为输入,以实现对不同数据的处理;函数执行后,还可以反馈相应的处理结果。
- 函数是一个功能抽象:完成特定功能,与黑盒类似,对函数的使用不需要了解函数内部实现原理,只要了解函数的输入输出方式。
- 分类:
1)用户定义函数:用户自己编写的子程序
2)系统自带函数及第三方函数:Python内嵌的函数(如abs()、map())、Python标准库中的函数(如 math 库中的 sqrt() )等 - 使用函数的目的
1)降低编程难度
2)代码复用
11.2 函数定义
- python 定义一个函数使用 def 保留字,语法形式如下:
def <函数名>(<参数列表>):
<函数体>
return <返回值列表>
函数名
<name>
:可以是任何有效的Python标识符。参数列表
<parameters>
:是调用函数时传递给它的值(可以由零个,一个或者多个参数组成),当有多个参数时,各个参数用逗号分隔。函数体
<body>
:函数被调用时执行的代码,由一个或多个语句组成函数调用的一般形式:
<name>(parameters)
11.3 函数定义 Tips
- 不需要说明形参类型,Python 解释器会根据实参的值
自动推断
形参类型。 - 不需要指定函数返回值类型,这由函数中 return 语句返回的值的类型来确定。如果函数没有明确的返回值,Python 认为返回空值 None。
- 即使该函数不需要接受任何参数,也必须保留一对空的英文半角圆括号。
- 函数头部括号后面的
冒号
必不可少。 - 函数体相对于 def 关键字必须保持一定的
空格缩进
。
函数定义示例1
- 定义函数
def add1(x):
x = x + 1
return 1
- 函数功能:将传给它的数值增1,返回增加后的值 return 语句:结束函数调用,并将结果返回给调用者。
- return 语句是可选的,可出现在函数体任意位置没有 return 语句,函数在函数体结束位置将控制权返回给调用方。
函数定义示例2
- 编写一个程序打印“Happy Birthday”的歌词。
标准的歌词:Happy Birthday to you! Happy Birthday to you! Happy Birthday to you, dear <insert-name> Happy Birthday to you!
方法一:使用4个 print 语句
print("Happy Birthday to you!")
print("Happy Birthday to you!")
print("Happy Birthday to you, dear Jack!")
print("Happy Birthday to you!")
方法二:使用函数来打印歌词的第一、二、四行
def happy():
print("Happy Birthday to you!")
happy()
happy()
print("Happy Birthday to you, dear Jack!")
happy()
写出给 Jack 和 Tom 唱生日歌的程序
方法三:函数嵌套调用、分别定义singJack()和singTom()函数
def happy():
print("Happy Birthday to you!")
def singJack():
happy()
happy()
print("Happy Birthday to you, dear Jack!")
happy()
def singTom():
happy()
happy()
print("Happy Birthday to you, dear Tom!")
happy()
singJack()
print()
singTom()
方法四:简化程序,编写通用函数sing()函数唱生日歌
def happy():
print("Happy Birthday to you!")
def sing(person):
happy()
happy()
print("Happy Birthday to you,", person + "!")
happy()
sing("Jack")
print()
sing("Tom")
结果:
Happy Birthday to you!
Happy Birthday to you!
Happy Birthday to you, Jack!
Happy Birthday to you!
Happy Birthday to you!
Happy Birthday to you!
Happy Birthday to you, Tom!
Happy Birthday to you!
11.4 函数调用
- 函数调用执行的四个步骤:
1)调用程序在调用处暂停执行。
2)函数的形参在调用时被赋值为实参。
3)执行函数体。
4)函数被调用结束,给出返回值。
def happy():
print("Happy Birthday to you!")
def sing(person):
happy()
happy()
print("Happy Birthday to you,", person + "!")
happy()
sing("Jack")
print()
sing("Tom")
11.5 函数参数传递
- 可选参数和可变数量参数。
- 在定义函数时,有些参数可以存在默认值。
- 在函数定义时,可以设计可变数量参数,通过参数前增加星号(*)实现。
def dup(str, times = 2):
print(str * times)
dup("knock~")
dup("knock~", 4)
结果:
knockknock
knockknockknockknock
11.6 函数返回值
- return 语句:程序退出该函数,并返回到函数被调用的地方。
- return 语句返回的值传递给调用程序。
- Python 函数的返回值有两种形式:
1)没有返回值:无返回值的 return 语句等价于 return None
2)返回一个或多个值 - 返回值可以是一个变量,也可以是一个表达式
def square(x):
y = x*x
return y
def square(x):
return x*x
11.7 lambda 函数
- lambda 保留字用于定义一种特殊的函数——匿名函数,又称 lambda函数
- 匿名函数并非没有名字,而是将函数名作为函数结果返回,如下:
<函数名> = lambda <参数列表> : <表达式> - lambda 函数与正常函数一样,等价于下面形式:
def <函数名>(<参数列表>):
return <表达式>
- 简单说,lambda 函数用于定义简单的、能够在一行内表示的函数,返回一个函数类型。
f = lambda x,y : x+y
lambda函数示例
filter 操作 python 语法实现
print [x for x in foo if x % 3 == 0]map 操作 python 语法实现
print [x * 2 + 10 for x in foo]
foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
print (list(filter(lambda x: x % 3 == 0, foo)))
print (list(map(lambda x: x * 2 + 10, foo)))
结果:
[18, 9, 24, 12, 27]
[14, 46, 28, 54, 44, 58, 26, 34, 64]
11.8 lambda 函数特点
- lambda 的使用大量简化了代码,使代码简练清晰。但是值得注意的是,这会在一定程度上降低代码的可读性。
- lambda 定义了一个匿名函数。
- lambda 并不会带来程序运行效率的提高,只会使代码更简洁。
- 如果可以使用 for .. in … if 来完成的,坚决不用 lambda。
- 如果使用 lambda,lambda 内不要包含循环,如果有,建议定义函数来完成,使代码获得可重用性和更好的可读性。
- 总结:lambda 是为了减少单行函数的定义而存在的。
11.9 变量作用域
- 一个程序中的变量包括两类:
全局变量
和局部变量
。 - 全局变量指在
函数之外
定义的变量,一般没有缩进,在程序执行全过程
有效。 - 局部变量指在
函数内部使用
的变量,仅在函数内部有效,当函数退出时变量将不存在。
n = 1
def func(a, b):
global n
n = b
c = a*b
return c
s = func("knock~", 4)
print(s, n)
结果:
knockknockknockknock 4
11.10 递归
- 递归定义:函数定义中使用函数自身的方法。
- 递归在数学和计算机应用中非常强大,能够非常简洁的解决很多问题。
- 经典递归例子:阶乘。
n! = n(n-1)(n-2)(n-3)…(1)
5! = 5(4)(3)(2)(1)
n! = n(n-1)!
- 阶乘的递归定义函数:
def fact(n):
if n == 0:
return 1
else:
return n* fact(n-1)
print(fact(5))
结果:
120
11.11 递归示例:字符串反转
方法一:字符串转换为字符列表,反转列表,列表转换回字符串。
def reverseStr(s):
ls = list(s)
ls.reverse()
s = "".join(ls)
print(s)
str = "sdfadfw8r873r323230"
reverseStr(str)
结果:
032323r378r8wfdafds
方法二:递归
- 将字符串分割成首字符和剩余子字符串
- 反转了剩余部分后把首字符放到末尾,整个字符串反转就完成了
def reverseRecu(s):
if len(s) <= 0:
return ""
else:
return reverseRecu(s[1:]) + s[0]
str = "sdfadfw8r873r323230"
print(reverseRecu(str))
结果:
032323r378r8wfdafds
12、类与对象
12.1 面向过程与面向对象
程序包括
数据:数据类型、数据结构
处理过程:算法两种程序设计思想
1)面向过程:以操作为中心、面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度(C语言)
2)面向对象:以数据为中心、把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递(Python)
12.2 面向过程与面向对象
Python 虽然是解释型语言,但从设计之初就已经是一门面向对象的语言,对于 Python 来说
一切皆为对象
。Python 中对象的概念很广泛,Python 中的一切内容都可以称为对象,而不一定必须是某个类的实例。例如,字符串、列表、字典、元组等内置数据类型都具有和类完全相似的语法和用法。
12.3 对象例子
人
数据:姓名,出生日期,身高,体重,…
操作:计算年龄,判断体重是否标准,…电视机
数据:型号,厂商,尺寸,频道数,…
操作:开机,关机,调频道,调音量,…室内环境
数据:温度,湿度,容积,…
操作:调节温度,调节湿度,换算容积单位
12.4 类概述
- 类是类型概念的发展
1)对象是广义的“数据值”。
2)对象所属的数据类型就是“类”。
3)用于描述复杂数据的静态和动态行为。 - 类(class):描述相似对象的共性。包括
1)数据
2)操作:方法(method) - 对象是类的实例(instance)
12.5 类与对象
- 类是对现实事物的抽象
1)数据抽象,例如:从具体学生抽象出姓名,年龄,地址等数据。
2)行为抽象,例如:从学生日常行为抽象出选课,加入社团等操作。
3)于是产生了类 Student 的定义。 - 抽象可以在多个层次上进行
例如:学生-人-动物-生物
12.6 类封装的好处
- 安全:对象自己的方法处理自己的数据。
- 易用:使用者无需了解内部实现细节。
- 易维护:实现者修改内部实现不会影响使用者。
- 标准化:同类甚至不同类的对象对使用者都呈现同样的操作界面。
12.7 类定义
实例化后,可以使用其属性。
class <类名>:
<方法定义>
12.8 类对象
- 类对象支持两种操作:属性引用和实例化。
- 属性引用使用和 Python 中所有的属性引用一样的标准语法:obj.name。
- 类对象创建后,类命名空间中所有的命名都是有效属性名。
12.9 Person 类
Person 类定义
这是一个学校 Python 定义的一个 Person类
class Person:
# 下面定义了一个类变量
hair = 'black'
def __init__(self, name='Charlie', age=8):
# 下面为 Person 对象增加2个实例变量
self.name = name
self.age = age
# 下面定义了一个say方法
def say(self, content):
print(content)
注释:
- 类有一个名为
__init__()
的特殊方法(构造方法),该方法在类实例化时会自动调用 - 类的方法与普通的函数只有一个特别 的区别—-他们必须有一个额外的第一个参数名称,按照惯例它的名称是self
12.10 Person 类实例化与使用
# 调用Person类的构造方法,返回一个Person对象
# 将该Person对象赋给p对象
p = Person()
# 输出p的name、age实例变量
print(p.name, p.age) # Charlie8
# 访问p的name实例变量,直接为该实例变量赋值
p.name = '李刚'
# 调用p的say()方法,声明say()方法时定义了2个形参
# 但第一个形参(self)是自动绑定的,因此调用该方法只需为第二个形参指定一个值
p.say('Python语言很简单,学习很容易!')
# 再次输出p的name、age实例变量
print(p.name, p.age) # 李刚 8
结果:
Charlie 8
Python语言很简单,学习很容易!
李刚 8