Python笔记
数字
在 Python 的数字有 4 种数据类型,分别为:
- int(有符号整型)
- long(长整型)
- float(浮点型)
- complex(复数)
可以通过函数type()
获取当前的数据类型
1 | print(type(123)) |
上面示例的运行结果如下:
1 | <class 'int'> |
使用isinstance()
函数可以判断一个对象是否是一个已知的具体类型
1 | isinstance(object, classinfo) |
object——实例对象
classinfo——可以是直接或间接类名,基本类型或者由他们组成的元组
1 | print(isinstance(123, int)) |
上面示例的运行结果如下:
1 | True |
整型
整型的意思就是整数,例如:-1、-10、1、23333
进制
- 十进制:正常写就 ok ,所有的数字都默认是十进制的。
- 二进制:在最前面添加
0b
的前缀,并且组成部分必须只能由 0 或者 1 组成,如: 0b10101010101 - 八进制:在最前面添加
0o
的前缀,并且组成部分必须只能有 0~7 的数字组成,如:0o12345670 - 十六进制:在最前面添加
0x
的前缀,并且组成部分由 09 和 AF 组成,如:0xdb273dc(注意:字母大小写不做区分,也可以写成 0xDB273DC )
浮点数
简单讲,浮点数就是带小数点的数字,且浮点数只能是十进制的数字
同样,分数也是浮点数的一种,如:0.5、0.3333333333333333等
复数
- 有理数:指两个整数的比。简单讲就是整数 + 有限或者无限循环小数
- 无理数:简单讲就是无限不循环小数
有理数和无理数加在一起成为实数,实数之外还有一种数叫复数
复数:z = a + bi(a、b均为实数)的数称为复数,其中a称为实部,b称为虚部,i称为虚数单位
在 Python 中,复数的表现方式如下:
1 | print(1+1j) |
结果如下:
1 | (1+1j) |
那么在python中如何获取实部和虚部呢?
1 | print((2.46+1.37j).real) |
结果如下:
1 | 2.46 |
布尔值
布尔值只有两个值,true和false,常用于各种逻辑判断中
1 | print(123 == 123.0) |
结果如下:
1 | True |
注意:
==
只能用来做数值的比较,并不会比较当前的数据类型,所以 123 和 123.0 是相等的。而 ‘123’ 不等于 123 则是因为 ‘123’ 是字符串,不能数值运算,而 123 是数字
字符串
字符串是由字符组成的一串有限序列,如:’homra’、”homra”
注意: ” 或者 “” 表示的是空字符串,空字符串和 null 是不一样的
字符串外面的包裹可以是单引号,也可以是双引号,需要注意的是单引号和双引号一定是成对出现的,不可混合使用
如果非要组合使用,我们可以看如下案例:
1 | print('小明说:"吃了吗?"') |
还可以使用连续三个单引号或者双引号,它可以使得中间被包裹起来的一个字符串跨多行,字符串中可以包含换行符、制表符以及其他特殊字符,示例如下:
1 | print(''' |
打印结果如下:
1 | 这是一个多行字符串的实例 |
转义
简单说,就是将字符原有的含义转换了
Python支持的转义字符如下:
符号 | 含义 |
---|---|
\ | 反斜杠符号 |
\‘ | 单引号 |
\" | 双引号 |
\a | 响铃 |
\b | 退格(Backspace) |
\000 | 空 |
\n | 换行 |
\v | 纵向制表符 |
\t | 横向制表符 |
\r | 回车 |
\f | 换页 |
\oyy | 八进制数,yy 代表的字符,例如:\o12 代表换行,其中 o 是字母,不是数字 0 |
\xyy | 十六进制数,yy代表的字符,例如:\x0a代表换行 |
\other | 其它的字符以普通格式输出 |
如果想打印出字符\t,而并不是希望当作横向制表符进行处理,该怎么办?
可使用如下两种解决方案:
1 | print("横向制表符:\\t") |
- 第一种是在转义符号前面再加一个转义符号
\
,负负得正。 - 第二种是在这个字符串的外面加一个 r (大小写均可)
常用方法
len()
获取字符串长度:
1 | print(len('I like Python!')) |
+
字符串拼接:
1 | a = "Hello" |
*
重复输出字符串
1 | print("a * 2 输出结果:", a * 2) |
通过索引获取字符串中的字符,第一个字符的索引为0
1 | print("a[1] 输出结果:", a[1]) |
[:]
截取字符串,遵循左闭右开原则
1 | print("a[1:4] 输出结果:", a[1:4]) |
in
包含,可以判断一个字符串中是否包含指定的字符串,并返回true或false
1 | if "H" in a: |
not in
不包含,返回的同样是布尔值
1 | if "M" not in a: |
变量
在 Python 中使用变量,有一个和 Java 最大的不同是无需先声明,直接在赋值的时候就完成了声明
如果我们直接使用一个没有赋值的变量,会直接报错
1 | name = "小红" |
如果我们不在需要这个变量,可以通过Python提供的del来删除这个变量
1 | del name |
变量类型转换
如果不同类型的变量进行拼接,会怎么样呢?
例如我们使用一个字符串加上一个整型:
1 | print('123' + 123) |
这句话的含义是告诉我们,字符串只能连接一个字符串,不能连接一个整型
所以我们需要统一变量类型,这里涉及到类型的强制转换
- float() 函数,将其他类型数据转为浮点数
- str() 函数,将其他类型数据转为字符串
- int() 函数,将其他类型数据转为整型
所以我们可以把代码修改为:
1 | print('123' + str(123)) |
如果我们将一个整型和一个浮点数进行相加会怎样?
这里涉及到了类型的提升:
1 | print(123.5 + 123) |
如果是一个浮点型强转成整型会怎样?
1 | print(int(123.7)) |
从示例可以看出,强制类型降级的时候,会直接抹去末尾的小数,并不是四舍五入
如果希望四舍五入,有如下两种方式可以实现:
1 | // 加0.5实现四舍五入 |
运算符
运算符可分以下几类:
- 算术运算符
- 比较运算符
- 赋值运算符
- 逻辑运算符
- 成员运算符
- 身份运算符
算数运算符
包含我们常用的加减乘除,也包含程序中常见的取模、取幂、取整除等
运算符 | 描述 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
% | 取模-返回除法的余数 |
** | 幂-返回x的y次幂 |
// | 取整数-向下取接近除数的整数 |
1 | a = 5 |
计算结果如下:
1 | 1. c 的值为: 15 |
如果是不同类型的数据进行运算,会发生隐式类型转换
类型转换的规则由低等到高等转换
bool
(布尔) < int
(整型) < float
(浮点型) < complex
(复数)
1 | a = 1 |
计算结果如下:
1 | c 的值为: 2.5 ,c 的类型为: <class 'float'> |
常用的内置函数
函数 | 描述 |
---|---|
abs(x) | 返回一个数的绝对值。实参可以是整数或浮点数。如果实参是一个复数,返回它的模 |
complex([real[, imag]]) | 返回值为 real + imag*1j 的复数,或将字符串或数字转换为复数 |
divmod(a, b) | 它将两个(非复数)数字作为实参,并在执行整数除法时返回一对商和余数 |
float([x]) | 返回从数字或字符串 x 生成的浮点数 |
pow(x, y[, z]) | 返回 x 的 y 次幂;如果 z 存在,则对 z 取余(比直接 pow(x, y) % z 计算更高效)。两个参数形式的 pow(x, y) 等价于幂运算符: x**y |
round(number[, ndigits]) | 返回 number 舍入到小数点后 ndigits 位精度的值。 如果 ndigits 被省略或为 None,则返回最接近输入值的整数 |
sum(iterable[, start]) | 从 start 开始自左向右对 iterable 中的项求和并返回总计值。 start 默认为 0。 iterable 的项通常为数字,开始值则不允许为字符串 |
bin(x) | 将一个整数转变为一个前缀为“0b”的二进制字符串 |
oct(x) | 将一个整数转变为一个前缀为“0o”的八进制字符串 |
hex(x) | 将整数转换为以“0x”为前缀的小写十六进制字符串 |
chr(i) | 返回 Unicode 码位为整数 i 的字符的字符串格式 |
ord(c) | 对表示单个 Unicode 字符的字符串,返回代表它 Unicode 码点的整数 |
bool([x]) | 返回一个布尔值,True 或者 False |
1 | print("11. -1 的绝对值为:", abs(-1)) |
测试结果如下:
1 | 11. -1 的绝对值为: 1 |
比较运算符
从字面意思来理解,比较运算符就是比较两个数值或者字符串类型的数据,返回一个布尔值
运算符 | 描述 |
---|---|
== | 等于,比较对象是否相等 |
!= | 不等于,比较两个对象是否不相等 |
> | 大于,返回x是否大于y |
< | 小于,返回x是否小于y |
>= | 大于等于,返回x是否大于等于y |
<= | 小于等于,返回x是否小于等于y |
赋值运算符
Python中,使用=表示赋值,也可以使用+=、-=对赋值方式进行简化
常见的赋值表达式如下:
运算符 | 描述 |
---|---|
= | 赋值运算符 |
+= | 加法赋值运算符 |
-= | 减法赋值运算符 |
*= | 乘法赋值运算符 |
/= | 除法赋值运算符 |
%= | 取模赋值运算符 |
**= | 幂赋值运算符 |
//= | 取整除赋值运算符 |
逻辑运算符
逻辑运算符有三种,分别是与、或、非
运算符 | 描述 |
---|---|
and | 逻辑”与”运算符,只有当and两边都是真,结果才是真 |
or | 逻辑”或”运算符,只要or任意一边是真,结果就是真 |
not | 逻辑”非”运算符,反转逻辑值 |
成员运算符
成员运算符用来判断在指定的序列中有没有找到目标值,这个序列可以是字符串、列表和元祖
- in : 如果在指定的序列中找到值返回
True
,否则返回False
- not in : 如果在指定的序列中没有找到值返回
True
,否则返回False
身份运算符
身份运算符用于比较两个对象的存储单元
- is :
is
是判断两个标识符是不是引用自一个对象 - is not :
is not
是判断两个标识符是不是引用自不同对象
1 | a = 20 |
注意:id()
函数用于获取对象内存地址
输出结果如下:
1 | a 和 b 有相同的标识 |
如果两个数值一样的变量,Python并不会重新开辟内存空间,而是会复用已有的内存空间
顺序结构
顺序结构是指做一件事是有顺序性的,按照操作步骤一步一步完成
1 | width = input("请输入长方形的宽:") |
分支结构
Python条件语句是通过一条或多条语句的执行结果(true或false),来决定执行的代码块
1 | weight = input("请输入您当前的体重:") |
循环结构
循环结构就是一直做某件事,直到满足某种条件,一定要给出跳出循环的条件,否则就是死循环
1 | happy = 0 |
for循环
for循环的使用格式
1 | for <variable> in <sequence>: |
这里的
1 | for index in "Python": |
输出的结果是:
1 | P |
如果需要使用for循环遍历数字序列,可以使用内置的range()函数
1 | for index in range(5): |
结果如下:
1 | 0 |
语法:range(start, stop[, step])
- start:计数从 start 开始
- stop:计数到 stop 为止,但不包括 stop
- step:步长,也叫间隔
如果步长为3,那么可以将代码改成:
1 | for index in range(0, 10, 3): |
输出结果如下:
1 | 0 |
循环中断
Python中有两种中断循环,分别是break
和continue
- break :结束本次循环,跳出所在的循环
- continue :中断本次循环,继续进行下一次循环
1 | happy = 0 |
运行结果如下:
1 | 学习使我快乐 当前快乐值为: 1 |
1 | happy = 0 |
运行结果如下
1 | 学习使我快乐 当前快乐值为: 1 |
内置数据结构
列表(list)
list
是Python中最常用的一种数据结构,它是一组用方括号括起来,逗号分隔的数据
创建列表:
1 | list1 = [1, 2, 3, 4, 5] |
输出结果:
1 | [1, 2, 3, 4, 5] |
列表中的数据类型可以是相同的,也可以是不同的
1 | list3 = [1, 2, 3, 'a', 'b'] |
输出结果:
1 | [1, 2, 3, 'a', 'b'] |
列表里也可以嵌套另一个列表
1 | list4 = [1, 2.33, 'a', list3] |
输出结果:
1 | [1, 2.33, 'a', [1, 2, 3, 'a', 'b']] |
空列表
1 | list5 = [] |
列表中常用的方法
type()
查看列表的类型
1 | print(type(list4)) |
结果如下:
1 | <class 'list'> |
列表名[索引]
通过索引取出列表的元素如果取出的索引位置不存在,则会直接抛出异常
Python中除了正索引还有负索引
0、1、2、3、4分别对应-5、-4、-3、-2、-1
1 | list1 = [1, 2, 3, 4, 5] |
列表1+列表2
使用加号连接列表
1 | print(list1 + list2) |
结果如下:
1 | [1, 2, 3, 4, 5, 'a', 'b', 'c', 'd', 'e'] |
for 变量 in 列表:
对列表元素进行for循环
1 | for i in list1: |
结果如下:
1 | 1 |
len(列表)
获取列表长度
1 | print(len(list1)) |
结果如下:
1 | 5 |
in
检查列表中是否存在某个元素
1 | print('a' in list1) |
结果如下:
1 | False |
del
列表名 删除列表
1 | list1 = [1, 2, 3, 4, 5] |
结果如下:
1 | [1, 2, 4, 5] |
max(list1)
返回列表中最大的值
1 | print(list1) |
结果如下:
1 | [1, 2, 4, 5] |
如果list元素类型不同无法比较大小,则会报错,如:
1 | list = [1, 2.33, 'a', [1, 2, 3, 'a', 'b']] |
结果如下:
1 | // ‘str’和‘float’无法比较大小 |
min(list1)
返回列表中最小的值
1 | print(list1) |
结果如下:
1 | [1, 2, 4, 5] |
列表切片
列表切片是指将列表中的一部分截取出来
语法:list[起始索引:终止索引:步长间隔]
注意:终止索引截取时是不会包含的
1 | list1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] |
结果如下:
1 | [3, 4, 5, 6, 7] |
列表常用方法
list.append(obj)
:在列表末尾添加新的对象
list.count(obj)
:统计某个元素在列表中出现的次数
list.extend(seq)
:在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的)
list.index(obj)
:从列表中找出某个值第一匹配项的索引位置
list.insert(index,obj)
:将对象插入列表
list.pop([index=-1])
:移除列表中的一个元素(默认最后一个),并且返回该元素的值
list.remove(obj)
:移除列表中某个值的第一个匹配项
list.reverse()
:反向列表中元素
元组(tuple)
元组和列表是非常类似的一种数据结构,那么他们有什么区别呢?
- 元组的元素不能修改
- 元组使用小括号,列表使用方括号
创建元组
用逗号隔开的就是元组,但是为了美观和代码可读性,一般加小括号
1 | tuple1 = "Python", "Java", 2011, 2015 |
结果如下:
1 | ('Python', 'Java', 2011, 2015) |
在创建元组的时候可以包含列表,如:
1 | tuple3 = ("Python", "Java", [1 ,2, 'python', 'java'], 2011, 2015) |
结果如下:
1 | ('Python', 'Java', [1, 2, 'python', 'java'], 2011, 2015) |
元组的基本操作
元组的基本操作和列表非常的类似,包括:
- 索引
- 切片
- 连接
- 复制
- 对内部元素循环
- 查找元组中是否有某元素
- 删除元组
- 返回元组中最大值和最小值
- 获取元组长度
1 | tuple4 = (0 ,1, 2, 3, 4, 5, 6, 7, 8, 9) |
结果如下:
1 | (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) |
列表和元组互相转化
1 | # 相互转化 |
结果如下:
1 | <class 'tuple'> |
总结
- 在列表外套一层
tuple()
就可以转为元组 - 在元组外套一层
list()
就可以转为列表
元组解包
1 | # 元组解包 |
结果如下:
1 | (1, 2, 3, 4, 5) |
解包就是将元组中的值,依次赋值给左侧的abcde
字典
字典由一组键(key)值(value)对组成的,类似于:
{key1:value1,key2:value2}
整个字典包括在花括号中
1 | dict1 = {'name': 'geekdigging', 'age': 2} |
结果如下:
1 | {'name': 'geekdigging', 'age': 2} |
注意:键必须是唯一的,但值则不必。值可以取任何数据类型,但键必须是不可变的
我们也可以创建多种类型混合的字典,如:
1 | dict2 = {(1, 2, 3): '123', 'name': 'geekdigging', 2: [1, 2, 3]} |
结果如下:
1 | {(1, 2, 3): '123', 'name': 'geekdigging', 2: [1, 2, 3]} |
还有另一种创建字典的方式:这种情况下,键只能为字符串类型,并且创建的时候字符串不能加引号,加上就会直接报语法错误
1 | dict3 = dict(name = 'geekdigging', age = 2) |
结果如下:
1 | {'name': 'geekdigging', 'age': 2} |
字典常用方法
获取某个键的值
语法:字典名[键]
,如果键不存在,则会直接报错
1 | print(dict1['name']) |
结果如下:
1 | geekdigging |
判断当前键是否存在
语法:键 in 字典
1 | dict1 = {"key1":"value1","key2":"value2"} |
结果如下:
1 | 请输入需要查询的键:key3 |
添加键值对
语法:字典名[键]=值
1 | dict1={} |
结果如下:
1 | {'aa': 123456} |
更新键值对
语法:字典名[键]=值
1 | dict1 = {"aa": 123456} |
结果如下:
1 | {'aa': 111111} |
删除键值对
语法:del 字典名[键]
1 | dict1 = {"aa": 1111, "bb": 2222} |
结果如下:
1 | 删除前字典: {'aa': 1111, 'bb': 2222} |
返回所有的键
语法:dict.keys()
,可以使用list()来转换为列表
1 | dict1 = {"aa": 1111, "bb": 2222, "cc": 3333} |
结果如下:
1 | dict_keys(['aa', 'bb', 'cc']) |
返回所有的值
语法:dict.values()
,可以使用list()来转换为列表
1 | dict1 = {"aa": 1111, "bb": 2222, "cc": 3333} |
结果如下:
1 | dict_values([1111, 2222, 3333]) |
将键值对以多个元组的形式存入列表
语法:dict.items()
1 | dict1 = {"aa": 1111, "bb": 2222, "cc": 3333} |
结果如下:
1 | dict_items([('aa', 1111), ('bb', 2222), ('cc', 3333)]) |
返回指定键的值,如果值不存在返回default值(默认为None)
语法:dict.get(key,default=None)
1 | dict1 = {"aa": 1111, "bb": 2222, "cc": 3333} |
结果如下:
1 | 1111 |
删除字典中指定键所对应的值,返回值为被删除的值
语法:dict.pop(key)
1 | dict1 = {"aa": 1111, "bb": 2222, "cc": 3333} |
结果如下:
1 | 1111 |
给字典中添加键值对,未指定值默认为None
语法:dict.setdefault(key,default=None)
,如果键已存在不做任何操作,不存在则添加
1 | dict1 = {"aa": 1111, "bb": 2222, "cc": 3333} |
结果如下:
1 | {'aa': 1111, 'bb': 2222, 'cc': 3333, 'dd': 4444, 'ee': None} |
将字典dict2的键值对更新到dict1里
语法:dict1.update(dict2)
1 | dict1 = {"aa": 1111, "bb": 2222, "cc": 3333} |
结果如下:
1 | {'aa': 1111, 'bb': 2222, 'cc': 3333, 'dd': 4444, 'ee': 5555} |
删除字典中所有元素
语法:dict.clear()
,删除的是字典元素不删除字典本身,删除后为空字典
1 | dict1 = {"aa": 1111, "bb": 2222, "cc": 3333} |
结果如下:
1 | 删除前: {'aa': 1111, 'bb': 2222, 'cc': 3333} |
返回一个字典的浅复制
语法:dict.copy()
,浅复制代表引用,操作复制后的对象会影响原对象
1 | dict3 = {'name': 'geekdigging', 'age': [1, 2, 3]} |
结果如下:
1 | 2380696613760 |
返回一个字典的深复制
语法:引入copy模块import copy
,copy.deepcopy(字典名)
1 | import copy |
结果如下:
1 | {'name': 'geekdigging', 'age': [2, 3]} |
集合
集合(set)是一个无序的不重复元素序列,元素需要是不可变类型
创建集合
语法:set = {xx1,xx2,xx3}
或set = set()
注意: 创建一个空集合必须用 set()
而不是 {}
,因为 {}
是用来创建一个空字典
1 | # 演示集合不可变元素 |
结果如下:
1 | {1, 2, 3, (1, 'geekdigging'), 'Python'} |
使用列表list创建集合
1 | # 使用 list 创建集合 |
结果如下:
1 | {1, 2, 3, 4, 5, 6, 7} |
使用元组tuple创建集合
1 | # 使用 tuple 创建集合 |
结果如下:
1 | {1, 2, 3, 4, 5, 6, 7} |
使用字符串创建集合
1 | # 使用字符串创建集合 |
结果如下:
1 | {'r', 'h', 'o', 'm', 'a'} |
集合常用方法
集合和列表、字典、元组等一样,都提供了很多内置的方法
1 | # 初始化数据 |
结果如下:
1 | 交集: {4, 5, 6} |
为集合添加元素
语法:set.add()
1 | set1 = {1, 2, 3} |
结果如下:
1 | {1, 2, 3, 4} |
语法:set.update()
1 | set1 = {1, 2} |
结果如下:
1 | {1, 2, (4, 5), 3, 4, 'python'} |
区别在于
add()
参数只能是单个元素,而update()
中的参数是一个 set 集合
随机移除元素
语法:set.pop()
1 | set1 = {1, 2, 3, 4, 5} |
结果如下:
1 | {2, 3, 4, 5} |
移除指定元素
语法:set.remove()
,若删除的元素不存在,则直接报错
1 | set1 = {1, 2, 3, 4, 5} |
结果如下:
1 | {1, 2, 3, 4} |
语法:set.discard()
,若删除的元素不存在,则什么也不做
1 | set1 = {1, 2, 3, 4, 5} |
结果如下:
1 | {1, 2, 3, 4, 5} |
清楚集合中所有元素
语法:set.clear()
1 | set1 = {1, 2, 3, 4, 5} |
结果如下:
1 | set() |
判断集合是否包含相同元素
语法:set.isdisjoint()
,没有返回True
,否则返回False
1 | set1 = {1, 2, 3, 4, 5} |
结果如下:
1 | False |
判断指定集合是否为该方法参数集合的子集
语法:set.issubset()
1 | set1 = {1, 2, 3} |
结果如下:
1 | True |
判断该方法的参数集合是否为指定集合的子集
1 | set1 = {1, 2, 3} |
结果如下:
1 | True |
函数
函数就是可以重复使用的代码
定义函数的规则:
- 函数代码块以 def 关键词开头
- 后接函数名称和圆括号
()
- 圆括号中可以使用参数
- 函数内容以冒号起始,并且缩进
- return 结束函数,可以选择性地返回一个值。不带 return 相当于返回 None
语法:def是系统关键字,可以用来定义函数
1 | def 函数名(形式参数): |
例如定义一个求两数之和的函数:
1 | def add(a, b): |
结果如下:
1 | 6 |
Python
中包含了很多内置函数
,无需我们定义,可以直接拿来使用
例如:print()
、 len()
、 type()
、 id()
等等
参数的传递
按照位置顺序传递
1 | add(1,2) |
按照赋值传递
1 | def subtraction(a, b): |
结果如下:
1 | 5 |
默认赋值传递
如果参数有两个,但是其中一个可能不会传递,这时我们可以给它一个默认值
1 | def division(a, b=1): |
结果如下:
1 | 5.0 |
可变长度参数传递(元组)
1 | def print_a(a, b): |
如果此时我们想打印100个参数怎么办?肯定不能增加100个形参
我们可以在参数前加一个*,表示这个参数是可变长参数
1 | def print_a(a, *b): |
结果如下:
1 | # 剩余的参数被转换成了元组的形式进行打印 |
可变长度参数传递(字典)
我们可以给参数前加两个*,表示可以传递的数据类型是字典
1 | def print_b(a, **b): |
结果如下:
1 | 1 {'q': 'q', 'w': 'w', 'e': 'e'} |
变量的作用域
内层函数的变量作用域仅在内层函数中,并不会覆盖到外层函数
局部变量只在当前函数中生效,出了函数就不生效了
1 | # 全局变量 |
结果如下:
1 | a = 1 |
匿名函数
当我们需要使用匿名函数的时候,可以使用 lambda
关键字来声明匿名函数
- lambda 只是一个表达式,函数体比 def 简单很多
- lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去
- lambda 函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数
语法:
1 | # 函数对象名 = lambda 形参:表达式 |
结果如下:
1 | 3 |
递归函数
一个函数调用自己就叫做递归
例如:我们想求n的阶乘
1 | def jiecheng(x): |
结果如下:
1 | 24 |
文件操作
什么是绝对路径和相对路径?
- 绝对路径:是指目录下的绝对位置,直接到达目标位置,通常是从盘符开始的路径。完整的描述文件位置的路径就是绝对路径
- 相对路径:相对路径就是指由这个文件所在的路径引起的跟其它文件(或文件夹)的路径关系
打开文件
常用语法:open(file, mode='r')
完整语法:open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)
参数说明:
- file: 必需,文件路径(相对或者绝对路径)
- mode: 可选,文件打开模式
- buffering: 设置缓冲
- encoding: 一般使用 utf-8
- errors: 报错级别
- newline: 区分换行符
- closefd: 传入的file参数类型
1 | str1 = open('D:/HelloWorld.txt', mode='r').read() |
结果如下:
1 | Hello World by Python!!! |
编码解码
Python3中,文件默认的编码方式是UTF-8,文本字符的常用编码有ASCII和Unicode
1 | str1 = '好好学习,天天向上' |
结果如下:
1 | <class 'str'> |
如果我们使用gbk
进行解码,则会报错
1 | print(a.decode('gbk')) |
结果如下:
1 | UnicodeDecodeError: 'gbk' codec can't decode byte 0x8a in position 26: incomplete multibyte sequence |
OS模块
我们可以使用内置函数来操作文件,我们也可以通过OS模块更简单的操作文件
OS模块是和操作系统相关的模块
建立一个test.txt
文件,内容为Hello World演示内容
1 | import os #导入os模块 |
结果如下:
1 | Hello World演示内容 |
新加内容
1 | file.write('\n好好学习 天天向上') |
这时候我们并没有指定文件的权限,所以会提示没权限写入报错
1 | io.UnsupportedOperation: not writable |
我们需要调整打开文件的权限
1 | file = open('test.txt',mode='a+') |
再次执行结果如下:我们可以正常写入文件了
1 | Hello World演示内容 |
如果我们对一个文件读取两次,但是只会打印一次,所以后面就读不到内容了
因为read()
读取所有内容,读取完后,游标是指在最后的
基础异常处理
捕获异常语法:
1 | try: |
迭代器
迭代器可以理解为for循环,Python还提供了另一种访问集合的方式
特点
- 可以记住遍历的位置的对象
- 迭代器从集合的第一个元素开始访问,直到所有的元素访问结束
- 迭代器只能向前不能后退
我们可以使用isinstance()
来判断当前对象是否可以迭代
迭代器不是Python的内置方法,需要先将迭代器引入
1 | from collections.abc import Iterable |
下面我们使用以下迭代器中的next()
方法
1 | from collections.abc import Iterable |
结果如下:
1 | TypeError: 'list' object is not an iterator |
list虽然是可以迭代的,但是list本身并不是迭代器,我们仍旧需要先将list转换成一个迭代器才能使用
1 | from collections.abc import Iterable |
结果如下:
1 | 1 |
生成器
在python中生成器是指用代码实现迭代器的的功能本质还是迭代器,只不过是代码实现迭代器功能。在python中生成器是由函数实现的,通常我们在函数中加入yeild就可以实现生成器
下面写一个简单的生成器的使用
1 | #定义一个函数 |
我们发现上面代码并没有执行,因为此时g
是一个生成器对象,生成器是不会自己运行的,需要我们手动调用next()
方法才会运行,并且每次遇到yield()
就会停止,继续调用next()
方法才会继续执行直到下一个yield()
1 | def func(): |
结果如下:
1 | 111 |
可以看出,yield
的两个作用
1、暂停当前函数的运行
2、返回yield
的值给调用者,即本例中调用next()
的print()
方法
所以打印出了111
和yield
返回的3
,但是并没有打印222
还有一个方法叫send()
,用法类似于next()
,都可以使函数继续运行,并且可以传送值给上一个yield
1 | def func1(): |
结果如下:
1 | g.send('哈哈哈') |
这里可以看出,错误原因是因为我们第一个yield
只能有如下三种写法
- 使用
next(g)
获取到第一个yield
,如果需要值则用变量接收 - 使用
g.__next__()
,这种方式等同于第一种 - 如果一定要使用
send()
方法,那么只能写成g.send(None)
经过修改后,我们的代码采用第三种方式了
1 | def func1(): |
结果如下:
1 | 哈哈哈 |
如果我们想打印出第一个yield
的值,那么我们可以修改代码为
1 | def func1(): |
结果如下:
1 | 6 |
这时候我们可以看到,打印出第一个yield
返回的值6
了
那么我们可以获取到最后一个yield
的返回值吗?
1 | def func1(): |
结果如下:这里获取的时候报错了
1 | 6 |
综上我们可以总结出四点
send
与next
一样,也是对生成器取值(执行一个yield
)的方法send
可以给上一个yield
传值第一次的取值永远都是
next
或send(None)
最后一个
yield
永远也得不到send
传的值
那么生成器可以做点什么呢?我们可以看如下代码
1 | def print_c(): |
结果如下:
1 | 执行 A |
因为
while
条件设置的是永真,所以这个循环是不会停下来的
这就是生成器的一个应用场景协程
协程
更贴切的解释是流水线,比如某件事情必须 A 先做一步, B 再做一步,并且这两件事情看起来要是同时进行的
Time模块
time是个跟时间相关的模块,我们可以先看如下代码
1 | import time |
结果如下:每隔一秒执行一次
1 | 0 |
不难理解,这里的time.sleep(1)
是一个按照指定时间睡眠的方法,单位是秒
接下来看一些其他的time
模块中的方法
1 | import time |
时间戳是从1970年1月1日0时0分0秒
起到现在的时长,时长的单位是秒
1 | import time |
我们可以通过strftime()
来自定义日期格式
这里列举一下日期格式化的符号:
- %y 两位数的年份表示(00-99)
- %Y 四位数的年份表示(000-9999)
- %m 月份(01-12)
- %d 月内中的一天(0-31)
- %H 24小时制小时数(0-23)
- %I 12小时制小时数(01-12)
- %M 分钟数(00=59)
- %S 秒(00-59)
- %a 本地简化星期名称
- %A 本地完整星期名称
- %b 本地简化的月份名称
- %B 本地完整的月份名称
- %c 本地相应的日期表示和时间表示
- %j 年内的一天(001-366)
- %p 本地A.M.或P.M.的等价符
- %U 一年中的星期数(00-53)星期天为星期的开始
- %w 星期(0-6),星期天为星期的开始
- %W 一年中的星期数(00-53)星期一为星期的开始
- %x 本地相应的日期表示
- %X 本地相应的时间表示
- %Z 当前时区的名称
- %% %号本身
calendar模块
我们先看一段代码
1 | import calendar |
结果如下:
1 | 2020 |
我们把 2020 年的日历打印出来了
- w = 每个日期之间的间隔字符数
- l = 每周所占用的行数
- c = 每个月之间的间隔字符数
除了返回全年的日历,我们还可以支持返回指定月份的日历:
1 | import calendar |
结果如下:
1 | April 2020 |
获取某月的总天数
1 | import calendar |
结果如下:
1 | 30 |
但是正常我们可以有更好的方式记住每个月多少天
一三五七八十腊,三十一天永不差
获取指定日期对应的星期数
1 | import calendar |
结果如下:
1 | # 需要注意的是 4代表星期五 日期从0到6 |
Excel操作
首先我们需要导入第三方模块xlrd
,如果没有的用如下命令安装
1 | pip install xlrd |
然后编写代码,指定xls
的具体位置
1 | import xlrd |
结果如下:
1 | ['1班', '2班', '3班'] |
获取行数和列数
1 | sheet1 = workbook.sheets()[0] |
结果如下:
1 | 6 |
获取整行和整列的数据(数据类型为列表)
1 | # 获取第 2 行内容 |
结果如下:
1 | ['小明', 76.0, 85.0, 95.0, ''] |
获取单元格的数据
1 | cell1 = sheet1.cell(1, 1).value |
结果如下:
1 | 76.0 76.0 85.0 85.0 |
获取日期类型数据
1 | date_value = xlrd.xldate_as_datetime(sheet1.cell_value(2, 3), workbook.datemode) |
结果如下:
1 | <class 'datetime.datetime'> 1900-04-01 00:00:00 |