杂项
约 2078 个字 81 行代码 预计阅读时间 8 分钟
关于输入输出
- print函数输出字符串,如果不打逗号是不会有空格的,打了逗号会有一个空格
print("hello""world")
# helloworld
print("hello" "world")
# helloworld
print("hello", "world")
# hello world
print("hello","world")
# hello world
- 格式化字符串
-
C风格:Python中一般不使用
-
str.format():Python风格的格式化字符串 -
f-string,新的格式化字符串 -
print(f"{3.1415926:.2}")输出是3.1,因为这个并不是保留两位小数而是保留两位有效数字,根本原因是没有指定类型,所以触发了默认的有效位数,正确的保留两位小数应该是print(f"3.1415926:.2f}") - Python的默认对齐方式是字符串左对齐(
<),数字右对齐>
关于类型转换
- Python始终是动态类型的语言,即便如今有什么类型提示之类的东西,类型提示的语法
def f(text : str) -> None int(num, base=10)如果是不写第二个参数,那么默认是十进制,可以处理各种类型,包括字符串,类比特对象或者是一个实数,但是不能为空
第二参数代表从多少进制转换到十进制,默认是十进制,如果写了第二个参数,第一个参数就必须是字符串
关于列表
- Python的list是支持存储不同类型的元素的
- Python的list可以比较大小,比较方法和字符串一样
[4, 5] * 3的结果为[4, 5, 4, 5, 4, 5]- 列表喜欢考切片slice,形如
[begin:end:step],但是可以省略参数,具体是哪个参数是按:来确定的,还有就是Python支持反向索引,最后一个元素的编号是-1 - 列表切片超出索引范围也不会报错,但是直接访问越界会报错
IndexError - 切片赋值语法,可以用切片接受一个别的列表,用来替换切片所表示的那一段
- 列表生成式可以带筛选条件
关于dict
- dict是没有默认值的,访问不存在的键会抛出错误,如果要修改键值应该先检查有没有
- 字典理论上是按照插入顺序保持元素的,但它不被认为是有序的
items返回键值对视图- dict创建在使用
dict()时是用的关键字参数,所以参数本身是不打引号的,比如d = dict(name="Alice", age=30) - 字典推导式:同时指定键值对,
d = {k:v for k,v in ["12", "34", "56"]},这个会发生拆包,比如"12"会被拆成"1"和"2"
关于set
- 添加是
add,删除是remove,还有一个discard用于删除,区别是不存在不会抛出错误 - 交集
|,并集&,差集是-,对称差集是^
关于字符串
内置方法的方法名看起来都是小写的
- 大小写处理,包括
upper(),lower()等 - 查找与替换,
find找不到会返回-1,但是index找不到会报错 - 分割与连接:分割使用
split,连接使用join - 判断类型:
isalpha(),isdigit(),isalnum(),islower(),isupper()
拆包和解包
i, *j = [1, 2, 3]的结果为i=1, j=[2, 3]print(*[1,2,3])的结果为1 2 3
列表去重
l = ['a', 'e', 'd', 'f', 'e']
l_ = list(set(l))
print(l_)
# sort 的关键字参数 key 传递的是一个可调用对象
# 这个对象接受一个参数,然后返回一个可比较的值
# 一般是函数(有可能是匿名的)
l_.sort(key=l.index)
print(l_)
关于垃圾回收
Python 显然是自动管理内存的,但是也提供了手动删除的方式del,可以del object[index/key...]或del object,如果索引不存在会抛出IndexError
关于内置函数
print(bin(12.5))这个是错的,因为bin只接受整数int("92",8),八进制怎么可能会有9的出现!?"34" in "1234"==True,"34" in "1234"确实是正确的,但是这个表达式的优先级有问题,in的优先级很低3 and 0 and "hello"这个的结果是0,0不是Falselist("abcd")的结果是['a','b','c','d'],list可以把一个可迭代对象转化成列表'3//11//2018'.split('/')这个是正斜杠,而不是反斜杠,着实难绷(print("{:>08s}".format(bin(31)[2:])),内置函数bin输出有个0b,[2:]其实是去除前缀Python只有字符串有find,列表那些应该用内置运算符in或者indexPython的random.randint(m,n)默认是闭区间,但random.randrange(m,n)是左闭右开的- 对于列表而言,
in只能检查单个数值是否在列表中,[2 ,3] in [1, 2, 3, 4]的结果是False,但是对于字符串而言,in可以检查某个字符串是否是另一个字符串的一部分 sort有两个关键字参数,一个是key,表示排序所使用的键,另一个是reverse表示是否要降序,如果你想要按照多个元素排序,那么可以用一个元组作为排序元素,sort是list的类方法,所以可以list.sort()sort需要看清楚排序对象是数字还是数字字符串join作用于字符串相当于先把字符串转化为列表,再拼接列表eval可以进行任意代码执行,但是第一个参数必须是字符串,比如a,b=eval(input().split())就是错误的abs是内置函数,fabs在math包中,abs可以用于复数,但是fabs不能
关于函数
- Python 允许使用内置函数名作为自定义函数名,但是会覆盖内置函数
- Python 如果当前文件名和包名相同会发生冲突,大概会报错找不到对应的库
from math import sin实际上并未导入math包,只导入了sin这个函数,输入math.sin会报错name 'math' is not definedimport math as m实际上导入了math包的,但是这个包现在的名称是m,直接用math会报错- 关键字参数必须在位置参数后面,位置参数已经对应了的参数不能重复赋值
python中的函数都是对象,所以如果去查函数的类型会返回function,但是用print去输出就不一样了,对此的解释为type()返回值的类型为type,返回值本身确实是function,但是要使用print输出需要调__repr__转化为字符串
关于异常
Python的异常捕获格式长这样,异常本质上是一个对象,所以可以自定义异常:
class MyError(Exception):
pass
try:
raise MyError("这是一个自定义异常")
except MyError as e:
print(f"捕获到自定义异常:{e}")
浅拷贝和深拷贝
对于简单类型,浅拷贝和深拷贝其实没什么区别,因为它们是不可变的,id()在Python中返回一个对象的“标识值”,这个标识值是一个整数,它在对象生命周期中是唯一且恒定的,可以把它理解为对象的地址。
a = 1
b = a
# 对于小的整数和字符串,Python 会进行对象复用,所以id可能相同
# 考试应该不至于这么考这么神经的,我实测也是 True
print(id(a) == id(b))
# 但是修改了之后就一定可以看出区别了
a = 2
print(id(a) == id(b)) # False,此时 a = 2 , b = 1
但是对于可变类型的拷贝,浅拷贝和深拷贝是可能有区别的,Python中的copy模块提供了浅拷贝和深拷贝,浅拷贝是copy.copy,深拷贝是copy.deepcopy
# 这里依次列举所有可能情况,非常容易混,主要是解释器有些时候的行为比较 confusing
l1 = [1, 2]
l2 = l1 # l1 和 l2 是同一个对象,因为赋值其实是赋值的指针
l3 = l1[::] # l1 和 l3 是不同的对象,因为切片是浅拷贝
l4 = copy.copy(l1) # l1 和 l4 是不同的对象,因为 copy.copy 是浅拷贝
l5 = copy.deepcopy(l1) # l1 和 l5 是不同的对象,因为 copy.deepcopy 是深拷贝
单层的列表深浅拷贝其实看不出区别,但是多层的列表深拷贝和浅拷贝是不同的
l1 = [1, [2, 3]]
l2 = l1.copy()
l3 = copy.deepcopy(l1)
l1[0] = 4
l1[1][0] = 5
print(l2) # [1, [5, 3]]
print(l3) # [1, [2, 3]]
其他
\ooo(三位八进制数)或者\xhh(两位十六进制数)都表示一个转义字符,比如\141表示a,\x61也表示a- ascell码
'0'是48,A是65,a是97,大小写之间差32 - float类型的默认输出会带小数点,比如
2//1的结果是2,但是2//1.0的结果是2.0 - 题目中的
□在程序填空题可以忽略 - Python 的
==是按照值相等,实际调用__eq__,而不是根据是不是同一个对象,is才是比较是不是同一个对象,即地址相等,id也是比较是不是为同一个对象 - Python的赋值是浅拷贝,准确说连拷贝都不是,实际上只是创建一个指针指向等号右边的对象,
copy.copy()、切片、list.copy()等是浅拷贝 - 序列赋值
a,b = "12",这个的结果是a="1", b="2" - 运算符优先级大概是幂、正负、乘除取模、加减、比较、逻辑否、与、或
**是右结合的split()会使用任意空白字符作为分隔符进行分割,split(' ')按单个空格进行分割,多个空格被视为多个分隔符,并且会生成空的子字符串
- 只有
str有find方法, enumerate()可以在遍历时获取索引
fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
print(f"索引: {index}, 水果: {fruit}")
'''
索引: 0, 水果: apple
索引: 1, 水果: banana
索引: 2, 水果: cherry
'''
运算符优先级
- 括号
() - 指数
** - 一元
+,- - 乘除
*,/,//,% - 加减
+,- - 比较
<,>,<=,>=,==,!= - 身份运算符:
in,not in - 成员运算符:
is,is not - 逻辑运算符:
not,and,or - 赋值运算符:
=,+=,-=,*=,/=,//=,%=