Python课程学习中的笔记,供自己复习用。
一、基础
1、注释
可以选中多行,按 Ctrl+/ 为每一行添加单行注释
# 单行注释
'''
多行注释1
'''
"""
多行注释2
"""
2、算术运算符
+
-
*
/ # Python3中9/2=4.5
// # 表示取整 9//2=4
% # 表示取余 9%2=1
3、变量与类型
数字型:int、bool(True/False)、float、complex(复数型)
非数字型:字符串、列表、元组、字典
Python2中整数分为int和long。
# 查看变量类型
type(name)
4、变量计算
数字型之间可以直接计算;(True 对应1 False 对应0)
字符串变量之间可以使用 + 拼接;
字符串可以使用 * 重复拼接相同的字符串;
# 打印50遍 -
print("-" * 50 )
数字型和字符串之间不能计算;
5、输入输出
print("Hello World")
name = input("请输入名字:") # 字符串类型
age = int(input("请输入年龄")) # 类型转换函数
grade = float(input("请输入成绩")) # 类型转换函数
# 格式化输出
print("我叫 %s ,今年 %03d岁了, 我的成绩是 %.2f ")
# %03d表示输出整数位数为3位,不足的部分用0补充
# %.2f表示保留小数点后两位
输出%,则需要使用%%
6、比较运算符
==
!= # Python2中还可以使用<>
>
<
>=
<=
7、逻辑运算符
与 and
或 or
非 not
8、赋值运算符
=
+=
-=
*=
/=
//=
%=
**=
二、判断与循环
1、if...else...
age = int(input("请输入年龄:"))
if age >= 18:
print("允许进入网吧")
else:
print("禁止入内")
2、elif
if 条件1:
条件1满足执行的代码
……
elif 条件2:
条件2满足时,执行的代码
……
elif 条件3:
条件3满足时,执行的代码
……
else:
以上条件都不满足时,执行的代码
……
3、石头剪刀布案例
import random
player = int(input("请输入(1剪刀 2石头 3布):"))
computer = random.randint(1, 3)
if player == computer:
print("平局")
else:
if (player == 1 and computer == 3) \
or (player == 2 and computer == 1) \
or (player == 3 and computer == 2):
print("你赢了")
else:
print("你输了")
print("电脑出了:%d" % computer)
4、while
i = 0
while i < 5:
print("hello")
i += 1
break
continue
三、函数
1、函数
def sum_2_num(num1, num2):
"""文档注释"""
return num1+num2
# 选择菜单中的view-quick Document查看文档注释
result = sum_2_num(1, 2)
print(result)
在调试时,
- F8 Step Over 可以单步执行代码,会把函数调用看作是一行代码直接执行
- F7 Step Into 可以单步执行代码,如果是函数,会进入函数内部
2、打印分割线&文档注释
def fun(char, time):
print(char * time)
def print_lines(num, char, time):
"""打印多行分割线
:param num: 分割线行数
:param num: 分割线行数
:param char: 分割线使用的字符
:param time: 分割线长度
:return: 无
"""
row = 1
while row <= num:
fun(char, time)
row += 1
print_lines(5, "&", 50)
3、模块
使用import导入.py结尾的模块
import d06
d06.print_lines(5, "*", 100)
print(d06.name) # 调用模块提供的全局变量
4、Pyc文件
C
compiled
编译过 的意思
操作步骤
a.浏览程序目录会发现一个 __pycache__
的目录
b.目录下会有一个 XXXX.cpython-35.pyc
文件,cpython-35
表示 Python
解释器的版本
c.这个 pyc
文件是由 Python 解释器将 模块的源码 转换为 字节码
Python
这样保存 字节码 是作为一种启动 速度的优化
字节码
Python
在解释源程序时是分成两个步骤的
- 首先处理源代码,编译字节码
- 再对 字节码机器码
- 有了模块的字节码文件之后,下一次运行程序时,如果在 上次保存字节码之后 没有修改过源代码,Python 将会加载 .pyc 文件并跳过编译这个步骤
- 当
Python
重编译时,它会自动检查源文件和字节码文件的时间戳 - 如果你又修改了源代码,下次程序运行时,字节码将自动重新创建
四、高级变量类型
1、列表List
在其它语言中叫做数组。
存储相同类型的数据。
索引从0开始。
name_list = ["张三", "李四", "王五"]
print(name_list)
# 取值与修改值:如果索引超出范围会报错
print(name_list[2])
name_list[2] = "abc"
print(name_list)
# 取索引:如果传递的数据不在列表中会报错
print(name_list.index("李四"))
# 增加数据
# append可以向列表末尾增加数据
name_list.append("王小二")
# insert可以在指定索引位置插入数据
name_list.insert(2, "小白")
print(name_list)
# extend可以把其它列表完整追加到当前列表末尾
name_list2 = ["aa", "bb", "cc"]
name_list.extend(name_list2)
print(name_list)
# 删除数据
# remove可以从列表中删除指定的数据,有相同数据则删除第一次出现的
name_list.remove("abc")
print(name_list)
# pop不带参数删除列表中最后一个元素
name_list.pop()
# pop删除指定位置元素,返回值为该元素
name_list.pop(3)
print(name_list)
# clear清空整个列表
name_list.clear()
print(name_list)
# del关键字可以用来删除数据
# del关键字本质上是把一个变量从内存中删除的
del name_list2[0]
print(name_list2)
name_list = ["zhangsan", "lisi", "wangwu", "wangwu"]
# 数据统计
# len统计列表中元素的总数
print(len(name_list))
# count统计列表中某一个数据出现的次数
print(name_list.count("wangwu"))
num_list = [45, 12, 13, 99, 1, 17]
# sort升序排序
num_list.sort()
print(num_list)
# sort(reverse=True)降序排序
num_list.sort(reverse=True)
print(num_list)
# reverse()反转
num_list.reverse()
print(num_list)
name_list = [1, 2, 3, 4, 5]
# 迭代遍历
for n in name_list:
print(n)
2、元组Tuple
元组的数据不能修改。
元组用()定义。
通常保存不同类型的数据。
可以定义空元组。
要定义只包含一个元素的元组,需要加逗号:info_tuple = (1, ),否则则不是tuple类型
info = ("小美", 18, 1.65, 18)
# 取值和取索引
print(info[2])
print(info.index(1.65))
# 统计计数
print(info.count(18))
# 统计元素个数
print(len(info))
# 循环遍历
for n in info:
print(n)
应用场景:
作为函数参数和返回值,可以一次性接收和返回任意多个数据;
格式字符串后面的()本质上就是元组;
info_tuple = ("小明", 18, 1.75)
print("名字叫%s,年龄%d,身高%.2f" % info_tuple)
info_str = "名字叫%s,年龄%d,身高%.2f" % info_tuple
print(info_str)
让列表不被修改,保护数据安全;
# 元组转换成列表
new_tuple = list(info)
print(type(new_tuple))
# 列表转换成元组
num_list = [1, 2, 3, 4]
new_list = tuple(num_list)
print(type(new_list))
3、字典
通常用来存储描述一个物体的相关信息;
列表是有序的对象集合,字典是无序的对象集合;
使用键值对存储数据,key是索引,value是数据,key必须是唯一的;
value可以是任何数据类型,key只能是字符串、数字或元组;
# 字典是无序的数据集合,通常print的顺序与定义的顺序不一致
xiaomei = {"name": "小美",
"age": 17,
"height": 1.65}
print(xiaomei)
# 取值
print(xiaomei["age"])
# 增加
xiaomei["weight"] = 50
# 修改
xiaomei["age"] = 21
print(xiaomei)
# 删除
xiaomei.pop("height")
print(xiaomei)
# 统计键值对数量
print(len(xiaomei))
# 合并字典
# 如果被合并的字典中包含已经存在的键值对,会覆盖原有键值对
h = {"height": 170}
xiaomei.update(h)
# 清空字典
print(xiaomei)
# 字典的遍历
xiaoming_dict = {"name": "小敏",
"qqnumber": "123456",
"phone": "10086"}
for k in xiaoming_dict:
print("%s是%s" % (k, xiaoming_dict[k]))
字典存储描述一个物体的相关信息,在开发中常把多个字典放在一个列表中;
card_list = [{"name": "张三",
"qq": "12345",
"phone": "110"},
{"name": "李四",
"qq": "54321",
"phone": "10086"}
]
for card_info in card_list:
for k in card_info:
print("%s -- %s" % (k, card_info[k]))
print("-"*50)
4、字符串
- 在 Python 中可以使用 一对双引号
"
一对单引号'
定义一个字符串
- 虽然可以使用
\"
\'
做字符串的转义,但是在实际开发中:
- 如果字符串内部需要使用
"
,可以使用'
定义字符串 - 如果字符串内部需要使用
'
,可以使用"
定义字符串
- 可以使用 索引指定位置的字符,索引计数从 0 开始
- 也可以使用
for
循环遍历 字符串中每一个字符
str = "hello"
print(str[1])
for s in str:
print(s)
str = "hello string"
# 统计长度
print(len(str))
# 统计一个子串出现的次数,不存在不会报错
print(str.count("l"))
print(str.count("abc"))
# 某一个子串出现的位置,不存在会报错
print(str.index("ing"))
判断类型:
string.isspace():如果 string 中只包含空格,则返回 True
string.isalnum():如果 string 至少有一个字符并且所有字符都是字母或数字则返回 True
string.isalpha():如果 string 至少有一个字符并且所有字符都是字母则返回 True
string.isdecimal():如果 string 只包含数字则返回 True,全角数字
string.isdigit():如果 string 只包含数字则返回 True,全角数字、⑴、\u00b2
string.isnumeric():如果 string 只包含数字则返回 True,全角数字,汉字数字
string.istitle():如果 string 是标题化的(每个单词的首字母大写)则返回 True
string.islower():如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True
string.isupper():如果 string 中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True
# 判断空白字符
str1 = " "
print(str1.isspace())
# 判断数字的三个方法
str2 = "11\u00b2"
str3 = "三十五"
print(str2.isdecimal()) # 数字
print(str2.isdigit()) # 数字+特殊数字
print(str3.isnumeric()) # 数字+特殊数字+汉字数字
查找和替换:
string.startswith(str):检查字符串是否是以 str 开头,是则返回 True
string.endswith(str):检查字符串是否是以 str 结束,是则返回 True
string.find(str, start=0, end=len(string)):检测 str 是否包含在 string 中,如果 start 和 end 指定范围,则检查是否包含在指定范围内,如果是返回开始的索引值,否则返回 -1
string.rfind(str, start=0, end=len(string)):类似于 find(),不过是从右边开始查找
string.index(str, start=0, end=len(string)):跟 find() 方法类似,不过如果 str 不在 string 会报错
string.rindex(str, start=0, end=len(string)):类似于 index(),不过是从右边开始
string.replace(old_str, new_str, num=string.count(old)):把 string 中的 old_str 替换成 new_str,如果 num 指定,则替换不超过 num 次
str = "hello world"
# 检查是否以XX开头
print(str.startswith("he"))
# 检查是否以XX结束
print(str.endswith("dd"))
# 查找:不存在会返回-1,如果用index方法,不存在会报错
print(str.find("wo"))
print(str.find("l", 0, 6))
# 替换:替换后的字符串作为返回值,原字符串不变
print(str.replace("llo", "pp"))
print(str)
大小写转换:
string.capitalize():把字符串的第一个字符大写
string.title():把字符串的每个单词首字母大写
string.lower():转换 string 中所有大写字符为小写
string.upper():转换 string 中的小写字母为大写
string.swapcase():翻转 string 中的大小写
文本对齐:
string.ljust(width):返回一个原字符串左对齐,并使用空格填充至长度 width 的新字符串
string.rjust(width):返回一个原字符串右对齐,并使用空格填充至长度 width 的新字符串
string.center(width):返回一个原字符串居中,并使用空格填充至长度 width 的新字符串
poem = ["登鹳雀楼",
"王之涣",
"白日依山尽",
"黄河入海流",
"欲穷千里目",
"更上一层楼"]
for s in poem:
print("|%s|" % s.center(10, " ")) # 中文空格
for s in poem:
print(s.ljust(10))
除去空白字符:
string.lstrip():截掉 string 左边(开始)的空白字符
string.rstrip():截掉 string 右边(末尾)的空白字符
string.strip():截掉 string 左右两边的空白字符
poem = ["登鹳雀楼\t",
"王之涣",
"白日依山尽\t\n",
"黄河入海流",
"欲穷千里目\n",
"更上一层楼"]
for s in poem:
# 去除空白字符
print(s.strip().center(10))
拆分和连接:
string.partition(str):把字符串 string 分成一个 3 元素的元组 (str前面, str, str后面)
string.rpartition(str):类似于 partition() 方法,不过是从右边开始查找
string.split(str="", num):以 str 为分隔符拆分 string,如果 num 有指定值,则仅分隔 num + 1 个子字符串,str 默认包含 '\r', '\t', '\n' 和空格
string.splitlines():按照行('\r', '\n', '\r\n')分隔,返回一个包含各行作为元素的列表
string.join(seq):以 string 作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串
song_str = "我告诉自己\t\n 再熬一熬\n 枯坐比久睡要好 \t所有热切的脸\r\t 冷淡下来 他们开始为你绘制一张革命之路"
# 拆分,默认以空白字符作为分隔符
song = song_str.split()
for s in song:
print(s.ljust(10))
# 连接
new_song = " ".join(song)
print(new_song)
切片:
字符串[开始索引:结束索引:步长]
切片内容不包含结束索引指向的元素;
num_str = "0123456789"
# 1. 截取从 2 ~ 5 位置 的字符串
print(num_str[2:6])
# 2. 截取从 2 ~ `末尾` 的字符串
print(num_str[2:])
# 3. 截取从 `开始` ~ 5 位置 的字符串
print(num_str[:6])
# 4. 截取完整的字符串
print(num_str[:])
# 5. 从开始位置,每隔一个字符截取字符串
print(num_str[::2])
# 6. 从索引 1 开始,每隔一个取一个
print(num_str[1::2])
# 倒序切片
# -1 表示倒数第一个字符
print(num_str[-1])
# 7. 截取从 2 ~ `末尾 - 1` 的字符串
print(num_str[2:-1])
# 8. 截取字符串末尾两个字符
print(num_str[-2:])
# 9. 字符串的逆序(面试题)
print(num_str[::-1])
对列表和元组同样可以进行切片;
5、内置函数
len(item) | 计算容器中元素个数 | |
del(item) | 删除变量 | del 有两种方式,也可以作为关键字使用 |
max(item) | 返回容器中元素最大值 | 如果是字典,只针对 key 比较 |
min(item) | 返回容器中元素最小值 | 如果是字典,只针对 key 比较 |
cmp(item1, item2) | 比较两个值,-1 小于/0 相等/1 大于 | Python 3.x 取消了 cmp 函数,直接使用比较运算符 |
6、运算符
运算符 | Python 表达式 | 结果 | 描述 | 支持的数据类型 |
+ | [1, 2] + [3, 4] | [1, 2, 3, 4] | 合并 | 字符串、列表、元组 |
* | ["Hi!"] * 4 | ['Hi!', 'Hi!', 'Hi!', 'Hi!'] | 重复 | 字符串、列表、元组 |
in | 3 in (1, 2, 3) | True | 元素是否存在 | 字符串、列表、元组、字典 |
not in | 4 not in (1, 2, 3) | True | 元素是否不存在 | 字符串、列表、元组、字典 |
> >= == < <= | (1, 2, 3) < (2, 2, 3) | True | 元素比较 | 字符串、列表、元组 |
In [1]: [1,2,3,4,5][1:3]
Out[1]: [2, 3]
In [2]: (1,2,3,4,5)[:-1]
Out[2]: (1, 2, 3, 4)
In [3]: [1,2]*5
Out[3]: [1, 2, 1, 2, 1, 2, 1, 2, 1, 2]
In [4]: [1,4]+[3,4]
Out[4]: [1, 4, 3, 4]
In [5]: "k" in "akfhjbnd"
Out[5]: True
In [6]: "k" not in "akfhjbnd"
Out[6]: False
In [7]: "a" in {"a":"mm"}
Out[7]: True
7、for循环
for 变量 in 集合:
循环体代码
else:
没有通过break退出循环,循环结束后,会执行的代码
for num in [1, 2, 3]:
print(num)
if num == 2:
break
else:
print("循环结束")
应用场景:数据搜索
students = [{"name": "xiaomei",
"age": 18,
"height": 1.68},
{"name": "xiaoyuan",
"age": 17,
"height": 1.65}]
find = "xiaomei"
for student in students:
if student["name"] == find:
print(student)
break
else:
print("没有找到")
五、变量与函数进阶
1、变量的引用
变量和数据是分开存储的,变量中保存着数据的地址,变量记录数据地址的动作叫做引用;
使用id()函数可以查看变量中保存数据所在的内存地址;
修改一个变量的值,本质上是修改了数据的引用;
在Python中,函数的实参和返回值都是通过引用传递的(本质上传递的是引用而不是数值);
2、可变类型与不可变类型
- 不可变类型,内存中的数据不允许被修改:
- 数字类型
int
,bool
,float
,complex
,long(2.x)
- 字符串
str
- 元组
tuple
- 可变类型,内存中的数据可以被修改:
- 列表
list
- 字典
dict
# 列表和字典都是可变类型
# 通过方法调用改变数据不会改变内存地址
# 通过赋值则会发生地址变化
demo_list = [1, 2, 3]
print("修改前的地址:%d" % id(demo_list))
demo_list.append(4)
demo_list.remove(2)
print("修改后的列表:%s" % demo_list)
print("修改后的地址:%d" % id(demo_list))
demo_list = []
print("赋值后的地址:%s" % id(demo_list))
字典的key只能使用不可变类型的数据
d = {123: '整数', (1,): '元组', 'abc': '字符串'}
Python
hash(o)
的函数,接收一个 不可变类型 的数据作为 参数,返回 结果是一个 整数(哈希值)哈希
算法,其作用就是提取数据的 特征码(指纹),相同的内容 得到 相同的结果,不同的内容 得到 不同的结果- 在
Python
键值对key
hash
后续 对字典的操作:增、删、改、查
- 键值对的
key
必须是不可变类型数据,因此字典的key只能使用不可变类型的数据;键值对的value
可以是任意类型的数据;
3、全局变量和局部变量
局部变量:只能在函数内部使用
函数执行结束后,函数内部的局部变量,会被系统回收
不同的函数,可以定义相同的名字的局部变量,但是彼此之间不会产生影响
def demo1():
num = 10
print("demo1内部的变量是%d" % num)
def demo2():
num = 99
print(num)
# print(num)
demo1()
demo2()
全局变量是在函数外部定义的变量,所有函数内部都可以使用这个变量
函数执行时会首先查找内部是否存在指定名称的局部变量,如果没有,再查找外部是否有指定名称的全局变量
在函数中,可以通过全局变量的引用获取对应的数据,但不允许直接修改全局变量的引用
为了避免局部变量和全局变量出现混淆,在定义全局变量时,有些公司会有一些开发要求,例如全局变量名前应该增加 g_
gl_
的前缀
num = 1
def demo1():
print(num)
def demo2():
# 只是定义了一个局部变量,不会修改到全局变量,只是变量名相同而已
num = 2
print(num)
demo1()
demo2()
如果在函数中需要修改全局变量,需要使用 global 进行声明
global关键字会告诉解释器,后面的变量是一个全局变量
num = 1
def demo1():
global num
num = 2
print(num)
def demo2():
print(num)
demo1()
demo2()
全局变量的位置
# 在开发时应该把模块中所有全局变量定义在所有函数上方
num = 123
def demo():
print(num)
print(str)
# print(name)
str = "456"
demo()
name = "xy"
代码结构从上到下依次为:
shebang
import
全局变量
函数定义
执行代码
4、函数返回多个值
函数使用元组返回多个值,使用多个变量接受返回的值:
def measure():
print("测量开始...")
temp = 30
wetness = 50
print("测量结束...")
# 用元组实现一次返回多个值,元组的小括号可以省略
return temp, wetness
result = measure()
print("今天的温度为%d,湿度为%d" % result)
# 需要单独处理元组元素时很不方便
print("温度:%d" % result[0])
print("湿度:%d" % result[1])
# 可以使用多个变量,一次接收函数的返回结果
gl_temp, gl_wetness = result
print(gl_temp)
print(gl_wetness)
5、交换两个变量的值
a = 1
b = 2
# 解法1 使用其他变量
t = a
a = b
b = t
print(a)
print(b)
# 解法2 不使用其他变量
a = a + b
b = a - b
a = a - b
print(a)
print(b)
# 解法3 python特有,等号右边是一个小括号省略的元组
a, b = b, a
print(a)
print(b)
6、函数的参数
无论传递的参数是可变还是不可变,只要针对参数使用赋值语句,会在函数内部修改局部变量的引用,不会影响到外部变量的引用
def demo1(num, num_list):
num = 100
num_list = [1, 2, 3]
print("在函数内:%d" % num)
print(num_list)
gl_num = 99
gl_numlist = [4, 5, 6]
demo1(gl_num, gl_numlist)
print("执行后:%d" % gl_num)
print(gl_numlist)
如果传递的参数是可变类型,在函数内部,使用方法修改了数据的内容,同样会影响到外部的数据
def demo(num_list):
num_list.append(4)
print(num_list)
gl_numlist = [1, 2, 3]
demo(gl_numlist)
print(gl_numlist)
在Python中,列表变量调用+=本质上是在执行列表变量的extend方法,不会修改变量的引用
def demo(num, list):
# 不可变类型,修改了变量的引用
num += 1
print(num)
# 可变类型,+=相当于调用extend,因此gl_list也会修改
list += [4, 5]
print(num)
gl_num = 9
gl_list = [1, 2, 3]
demo(gl_num, gl_list)
print(gl_num)
print(gl_list)
7、缺省参数
使用最常见的值作为默认值;
缺省参数必须在参数列表末尾;
如果有多个缺省参数,需要指定参数名;
gl_list = [7, 2, 5, 0]
gl_list.sort() # 默认升序
print(gl_list)
gl_list.sort(reverse=True)
print(gl_list)
def print_info(name, gender=True):
if gender:
print("%s是男生" % name)
else:
print("%s是女生" % name)
print_info("小明")
print_info("小美", False)
8、多值参数
参数个数不确定:
参数名前增加一个 *
可以接收元组,常起名叫args;
参数名前增加两个 *
可以接收字典,常起名叫kwargs;
def demo(num, *nums, **person):
print(num)
print(nums)
print(person)
demo(1)
demo(1, 2, 3, 4)
demo(1, 2, 3, 4, name="xy", age=17)
def sum_nums(*args):
sum = 0
for num in args:
sum +=num
print(sum)
sum_nums(1, 2, 3, 4)
9、元组和字典的拆包
- 在调用带有多值参数的函数时,如果希望:
- 将一个元组变量,直接传递给
args
- 将一个字典变量,直接传递给
kwargs
- 就可以使用拆包,简化参数的传递,拆包的方式是:
- 在元组变量前,增加一个
*
- 在字典变量前,增加两个
*
def demo(*args, **kwargs):
print(args)
print(kwargs)
gl_nums = [1, 2, 3]
gl_dict = {"name": "小明", "age": 18}
# 会把两个参数都作为元组元素传递给args
# demo(gl_nums, gl_dict)
demo(*gl_nums, **gl_dict)
10、函数的递归
函数内部调用自己;
一定要有递归出口;
在处理不确定的循环条件时,格外的有用,例如:遍历整个文件目录的结构
def sum_num(num):
if num == 1:
return 1
return num + sum_num(num -1)
print(sum_num(5))
。