Python基础
1. 运算符
1.1 算数运算符
- “+” 加 两个对象相加
- “-” 减 得到负数或一个数减去另一个数
- “*” 乘 两个数相乘或返回一个被重复若干次的字符串
- “/” 除 x除以y
- “%” 取模 返回除法的余数
- “**” 幂 返回x的y次幂
- “//” 取整除 往小的方向取整数
1.2 比较运算符
- “==” “!=” “>” “<” “>=” “<=”
1.3 赋值运算符
- “=” “+=” “-=” “*=” “/=” “%=” “**=” “//=”
1.4 逻辑运算符
a = 10, b = 20
- and x and y 布尔“与”–如果x为False,返回x的值,否则返回y的值
- or x or y 布尔“或”–如果x为True,返回x的值,否则返回y的值
- not not x 布尔“非”–如果x为False,返回True,否则返回False
1.5 位运算符
- “&” 按位与运算符:同1则1,其他为0
- “|” 按位与运算符:有1则1,无1则0
- “^” 按位与运算符:相异则1,相同则0
- “~” 按位取反运算符 ~x类似于-x-1
2. 选择循环结构
计算机之所以能做很多自动化的任务,因为它可以自己做条件判断,Python 条件语句是通过一条或多条语句的执行结果(True 或者 False)来决定执行的代码块。
2.1 if条件语句
2.1.1 小练习
小明身高1.75,体重80.5kg。请根据BMI公式(体重除以身高的平方)帮小明计算他的BMI指数,并根据BMI指数:
低于18.5:过轻
18.5-25:正常
25-28:过重
28-32:肥胖
高于32:严重肥胖
high = 1.75
weight = 80.5
BMI = weight/(high**2)
if BMI < 18.5:
print("过轻")
elif BMI < 25:
print("正常")
elif BMI < 28:
print("过重")
elif BMI < 32:
print("肥胖")
else:
print("严重肥胖")
过重
2.2 while循环
- 只要条件满足,就不断循环,条件不满足时退出循环
- 类似Java中的while…do,在Python中没有do…while
计算100以内所有偶数之和
while n > 0:
sum += n
n -= 2
print(sum)
2550
break语句(提前结束循环)
给定一个字符串s = ‘beautifulCode’
-
从前到后检查每个字母
-
如果是大写字母则停止检查并输出:有大写字母,第一个大写字母为%s
-
否则输出:无大写字母
s = 'beautifulCODe'
for a in s:
if a.isupper():
print("有大写字母,第一个大写字母为:",a)
break
else:
print("无大写字母")
有大写字母,第一个大写字母为: C
continue语句(不进行本次循环continue后的语句,直接开始下一次的循环)
计算1~100中奇数的和
i = 0
sum = 0
while i < 100:
i += 1
if i %2 ==0:
continue
sum += i
print(sum)
2500
3. 命名空间
命名空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的
命名空间提供了在项目中避免名字冲突的一种方法。各个命名空间是独立的,没有任何关系的,所以一个命名空间中不能有重名,但不同的命名空间是可以重名而没有任何影响
Python中一般有三种命名空间:
-
内置名称(built-in names):
- Python 语言内置的名称,比如函数名 abs、chr 和异常名称 BaseException、Exception 等等
-
全局名称(global names):
- 模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量
-
局部名称(local names):
- 函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量(类中定义的也是)
命名空间查找顺序:局部的命名空间 -> 全局命名空间 -> 内置命名空间
Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问
4. 数据容器
4.1 List列表
List使用**[]**创建,里面的元素可以是不同的类型,有序的
classmates = ['James', 'Kobe', 'Polo']
1.使用append()方法添加元素,该方法会在列表末尾位置添加数据元素
#list使用append方法改变的是list本身 没有变成一个新的列表 所以没有返回值
classmates.append('Irving')
print(classmates)
['James', 'Kobe', 'Polo', 'Irving']
2.使用insert()方法也可以向指定的索引位置增加元素
classmates.insert(3,'Jordan') #3是添加后的索引位置
print(classmates)
['James', 'Kobe', 'Polo', 'Jordan','Irving']
3.remove()方法适用于知道要删除的值的情况,可指定元素值进行删除
classmates.remove('Polo')
print(classmates)
['James', 'Kobe','Jordan','Irving']
4.pop()方法可指定索引位置进行元素的删除
classmates.pop(1)
print(classmates)
['James','Jordan','Irving']
5.reverse()方法可以将list中的元素进行反转
classmates.reverse()
print()
['Irving','Jordan','James']
6.使用index()方法可以指定元素,查找元素所在的位置
classmates.index('Irving')
0
7.切片
完整的切片操作需要提供三个参数:
- 起始位置:默认等于第一个位置
- 结束位置:默认等于最后一个位置
- 步长:默认等于1
#从classmates中提取元素'Irving','Jordan'
classmates[0:1:]
['Irving','Jordan']
4.2 tuple元组
tuple使用**()**创建和list非常类似,但是tuple一旦初始化就不能修改,有序的
tuple的使用可以使得代码更安全,防止错误赋值导致重要对象的改变
4.3 字典
将对象与其属性相关联起来,即键-值(key-value),具有极快的查找速度
字典的创建使用大括号 {} 包含键值对,并用冒号 : 分隔键和值,形成 键:值 对
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
dict字典中常见的方法:
- get:通过key获取value,还可以指定当key不存在时返回一个默认值
- pop:通过key删除kv键值对
- keys:返回所有的key
- values:返回所有的value
- items:将每个KV键值对转换成二元组并返回(一般用于遍历)
- clear:清空字典
- 通过in可以判断某个dict中是不是包含某个key
# 字典练习
# 字典是无序的 没有索引
dict_a = {"a": "b", "c": "d"}
print(dict_a) # 打印出来是'' ##{'a': 'b', 'c': 'd'}
# 新增一个键值对
dict_a['e'] = "f"
print(dict_a) ##{'a': 'b', 'c': 'd', 'e': 'f'}
# 更改一个键值对
dict_a['a'] = "B"
print(dict_a) ##{'a': 'B', 'c': 'd', 'e': 'f'}
# 输出键对应的值
print(dict_a['a']) ##B
# 列表和元组 key不能是可变的数据类型 列表和字典不能做key,只有元组可以
dict_c = {(1,2):(1,), ('a','b'):[1,2,3]}
print(dict_c)
# 1就是True,0就是False 后续定义的内容会更新前序的内容
dict_b = {'a': 1, 1: 1.1, 1.2: True, True: 'bbb', 0: 0, False: 1, None: 9}
print(dict_b) ##{'a': 1, 1: 'bbb', 1.2: True, 0: 1, None: 9}
# 弹出指定的键值对
dict_b.pop(1)
print(dict_b) ##{'a': 1, 1.2: True, 0: 1, None: 9}
# 输出字典的长度
print(dict_b.__len__()) ##4
# 查找键对应的值
print(dict_b.get(None)) ##9
# 输出所有的键形成的列表
print(dict_b.keys()) ##dict_keys(['a', 1.2, 0, None])
# 将键逐个输出
for i in dict_b.keys():
print(i)
## a
1.2
0
None
# 输出所有键值对形成的列表
print(dict_b.items()) ##dict_items([('a', 1), (1.2, True), (0, 1), (None, 9)])
# 常用的字典遍历方式
for k,v in dict_b.items():
print(k,v)
## a 1
1.2 True
0 1
None 9
# dict_b 是字典
print(1.2 in dict_b) ##True
# dict_b.keys()是列表
print(1.2 in dict_b.keys()) ##True
# dict_b.values()是列表
print(1.2 in dict_b.values()) ##False
# dict_b.items()是元组
print(('a,', 1) in dict_b.items()) ##False
4.4 set集合
set和dict类似,也是一组key的集合,但不存储value,由于key不能重复,所以,在set中,没有重复的key
- 创建一个set:可以使用花括号{}或者是set()方法进行创建
set_a = {1, 1, 2, 2, 3, 4, 5, 'a', 1.2, False, True}
print(set_a) # 自动去重和排序 键是唯一的
{False, 1, 2, 3, 4, 5, 1.2, 'a'}
- 定义一个空的集合
set_b = set()
print(set_b, type(set_b))
set() <class 'set'>
- set集合的增删改查
# 通过列表的方式转换为set集合
set_c = set([1, 2, 3, 4, 1, 3, 1.2, "a", "b", False])
print(set_c)
# 随机弹出
set_c.pop()
print(set_c)
# 删除指定元素 指定不存在的元素时会报错
set_c.remove(3)
print(set_c)
# 同remove 但可以指定不存在的元素 且不报错
set_c.discard('m')
print(set_c)
# 加入已存在的元素 不会报错 而是加进去之后自动去重
set_c.add('a')
print(set_c)
# 判断set_c是不是指定集合的子集
print(set_c.issubset({1, 2, 3, 4, 1.2, False, 'b', 'a'}))
# 判断指定集合是不是set_c的子集
print(set_c.issuperset({4, 1.2, 'b', 'a'}))
{False, 1, 2, 3, 4, 1.2, 'b', 'a'}
{1, 2, 3, 4, 1.2, 'b', 'a'}
{1, 2, 4, 1.2, 'b', 'a'}
{1, 2, 4, 1.2, 'b', 'a'}
{1, 2, 4, 1.2, 'b', 'a'}
True
True
- 并、交、差、集
set_d = {1, 3, 5, 6, 2, 7}
set_e = {1, 2, 3, 4, 5}
# 差集
print(set_e.difference(set_d))
print(set_d.difference(set_e))
# 并集
print(set_d.intersection(set_e))
# 交集
print(set_d.union(set_e))
{4}
{6, 7}
{1, 2, 3, 5}
{1, 2, 3, 4, 5, 6, 7}
4.5 遍历数据容器
4.5.1 列表的遍历
list_a = [[1, 2], [3, 4], [5, 6], [7, 8]]
fir i in list_a:
for j in i:
print(j)
1
2
3
4
5
6
7
8
for m in range(len(list_a)):
list_b = list_a[m]
for n in range(len(list_a[m])):
print(list_b[n]) # 输出同上
4.5.2 字典的遍历
dict_m = {1: 3.1, 'M': 'n', True: 2, False: False, (1, 2): 'Bob'}
for k,v in dict_m.items():
print(k,v)
1 2
M n
False False
(1, 2) Bob
4.6 列表生成式
4.6.1 编写列表生成式的方法:
- 写列表生成式时,先把生成的元素x * x放到前面
- 后面跟for循环,就可以把list创建出来
- for循环后面还可以加上if判断,例如仅将偶数筛选出来
- 还可以使用两层循环,例如生成ABC和XYZ中全部字母的排列组合
例:生成一个1~10奇数的列表
list_a = []
for i in range(1, 10):
if i % 2 == 1:
list_a.append(i)
print(list_a)
print([i for i in range(1, 10) if i % 2 == 1])
[1, 3, 5, 7, 9]
4.6.2 join方法的作用
用指定的符号来代替列表中的’,',只能作用于字符串列表
list_b=["1","2","3","4"]
str_a = '#'
print(str_a.join(list_b))
1#2#3#4
例:输出九九乘法表
for i in range(1, 10):
for j in range(1, i + 1):
print(f"{j}*{i}={i * j}", end="\t")
print()
# 从内往外,先除去内层for循环,并使用join方法,用\t使每列有间隙
for i in range(1, 10):
print("\t".join(([f"{j}*{i}={i * j}" for j in range(1, i + 1)])))
# 除去外层for循环
print(["\t".join([f"{j}*{i}={i * j}" for j in range(1, i + 1)]) for i in range(1, 10)])
# 使用join方法,用\n在','部分换行
print("\n".join(["\t".join([f"{j}*{i}={i * j}" for j in range(1, i + 1)]) for i in range(1, 10)]))
# 用以上两个列表推导式来理解'.join'的作用
4.7 冒泡排序
原理:两两比较,大的往后挪
list_a = [123, 23, 123, 4123, 534, 4, 13, 344243, 1213]
for i in range(len(list_a)):
for j in range(len(list_a)-1-i):
if list_a[j] > list_a[j+1]:
list_a[j],list_a[j+1] = list_a[j+1],list_a[j]
print(list_a)
[4, 13, 23, 123, 123, 534, 1213, 4123, 344243]
4.8 杨辉三角
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
思路:将杨辉三角看作一个二维数组,可以知道第一行的元素为:[1],由此定义这个二维数组为:Triangle = [[1]]
假设已知[1, 6, 15, 20, 15, 6, 1]
可知[1, 6, 15, 20, 15, 6, 1] = [1] + [ 6, 15, 20, 15, 6] + [1]
设:nnew_list = [1, 6, 15, 20, 15, 6, 1]
new_list = [ 6, 15, 20, 15, 6]
即:nnew_list = [1] + new_list + [1]
此时我们是找到new_list与上一个列表的关系即可
而上一个列表为[1, 5, 10, 10, 5, 1]
用for…in…循环很容易可以得到:
for j in range(len(old_list)-1):
new_list.append(old_list[j] + old_list[j+1])
由此就得到了new_list,依次向上寻找,得到一个old_list与数组有关的循环
for i in range(1,11):
old_list = Triangle[i-1]
最终完整代码如下:
triangle = [[1]]
for i in range(1,11):
old_list = triangle[i-1]
print(old_list)
new_list = []
for j in range(len(old_list)-1):
new_list.append(old_list[j]+old_list[j+1])
nnew_list = [1] + new_list +[1]
triangle.append(nnew_list)
用列表推导式表示为:
old_list = [1]
for i in range(1,11):
print(old_list)
new_list = [1] + [old_list[j] + old_list[j + 1]for j in range(len(old_list)-1)] + [1]
old_list = new_list
最终输出结果为:
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
5. 函数
如果不写return 默认返回的是空值
def 是函数定义的关键字 def 后接函数名 r是形参 3是实参
一个标准的缩进后是函数内的详细代码(函数体)
def area_of_circle(r):
PI = 3.14
S = PI * r * r
return S
S1 = area_of_circle(2)
print(S1)
print(round(area_of_circle(5.1),2)) # round()将输出结果保留两位小数
12.56
81.67
5.1 函数的参数
- Python的函数定义非常简单,但灵活度却非常大
- 除定义的必选参数外,还可使用默认参数、可变参数、关键字参数和命名关键字参数
- 使得函数定义出来的接口,不但能处理复杂的参数,还可简化调用者的代码
5.1.1 必选参数
又名位置参数,调用函数时必须按顺序提供,不多不少
例如:定义一个函数用于计算x的平方
def power(x):
return x*x
# 对于power函数来说,x就是一个位置参数,当调用函数时,必须传入有且仅有一个参数x
假如现在又要计算x3怎么办?可以再定义一个power3函数,但是如果要计算x4、x^5……怎么办?不可能定义无限多个函数,那可以把power(x)修改为power(x, n),再结合while循环用来计算x^n
def power(x,n):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
# 对于这个修改后的power(x, n)函数,可以计算x的任意n次方
# x和n,这两个参数都是位置参数
# 调用函数时,需要按照位置顺序依次将值传入并赋给参数x和n
print(power(3,3))
5.1.2 默认参数
给参数设置一个默认值,当你调用函数只给定一个参数时,函数依然可以调用
def power(x,n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
print(power(5) # 相当于计算了5
5.1.3 可变参数
可变:传入的参数个数可变 (形式:*args)
# 使用必选参数
def calc(numbers):
sum = 0
for n in numbers:
sum += n*n
return sum
# 因为只有一个必选参数,如果想要得到a^2 + b^2 + c^2 + …的类型,需要将a,b,c...组装成一个list或者tuple,即:
print(calc([1,2,3]))
print(calc((1,2,3,4)))
# 使用可变参数优化后,可以直接输入任意参数,在函数调用时自动组装为一个tuple
def calc(*numbers):
sum = 0
for n in numbers:
sum += n*n
return sum
print(clac(1,2,3))
5.1.4 关键字参数
关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict
def person(name,age,**kw):
print(name,age,'other:',kw)
# 在调用该函数时,可以只传入必选参数:
person('Michael',30) # Michael 30
# 也可以传入任意个数的关键字参数
person('Bob',35,city='Beijing',job='Engineer')
# Bob 35 {'city':'Beijing','job':'Engineer'}
5.1.5 命名关键字参数
对于关键字参数,函数的调用者可以传入任意不受限制的关键字参数。至于到底传入了哪些,就需要在函数内部通过kw检查
-
如果要限制关键字参数的名字,就可以用命名关键字参数,例如,只接收city和job作为关键字参数。这种方式定义的函数如下:
-
def person(name,age,*,city,job): print(name,age,city,job) #和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符*,*后面的参数被视为命名关键字参数
如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*了:
def person(name,age,*args,city,job):
print(name,age,args,city,job)
5.1.6 参数组合
- 顺序:必选参数、默认参数、可变参数、命名关键字参数和关键字参数
def f1(a,b,c=0,*args,d,e,**kw):
print(a,b,c,args,d,e,kw)
# f1函数的调用
f1(1,2,3,4,5,6,d=7,e=8,k1=9,k2=10,k3=11)
1,2,3,(4,5,6)d=7,e=8,{'k1':9,'k2':10,'k3':11}
5.2 递归函数
需要满足的两个条件:
- 自己调用自己
- 有停止条件
例:计算n的阶乘,即n! = n * ( n - 1 ) * ( n - 2 ) * ( n - 3 ) … 3 * 2 * 1
def fact(n):
if n == 1:
return 1
return n * fact(n - 1)
#在return语句中 fact(n - 1) 相当于自己调用自己
#当n=1时进行了特殊处理,即停止条件
#综上fact函数可以看做是一个递归函数
def fib(n):
if n <= 0:
return []
elif n == 1:
return [0]
elif n == 2:
return [0,1]
else:
list = fib(n-1)
list.append(list[-1]+list[-2])
return list
list_fib = fib(10)
print(list_fib)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]