方法一:切片拼接
# 例如
def str_pj(str, num):
if num != -1:
str = str[:num]+str[num+1:]
else:
str = str[:-1]
return str
print(str_pj('abcdefgh', -1))
# 终端显示
abcdefg
方法二:遍历拼接
# 例如
def str_pj(str, num):
str1 = ''
for i in range(len(str)):
if i != num:
str1 += str[i]
return str1
print(str_pj('abcdefgh', -1))
# 终端显示
abcdefg
方法三:枚举
# 例如
def str_pj(str, num):
str1 = ''
for index, item in enumerate(str):
if index != num:
str1 += item
return str1
print(str_pj('abcdefgh', -1))
# 终端显示
abcdefg
方法四:列表遍历拼接
# 例如
def str_pj(str, num):
lis1 = [i for i in str]
lis1.pop(num)
str1 = ''.join(lis1)
return str1
print(str_pj('abcdefgh', -1))
# 终端显示
abcdefg
方法一:用sort函数
# 例如
FileName = ["10.py", "2.py", "8.py", "6.py", "100.py"]
def res(x):
return int(x.strip('.py'))
FileName.sort(key=res)
print(FileName)
# 终端显示
['2.py', '6.py', '8.py', '10.py', '100.py']
方法二:删除’.py’,然后拼接
# 例如
FileName = ["10.py", "2.py", "8.py", "6.py", "100.py"]
lis1 = [int(i.strip('.py'))for i in FileName]
lis1.sort()
lis2 = [str(j)+'.py 'for j in lis1]
print(lis2)
# 终端显示
['2.py', '6.py', '8.py', '10.py', '100.py']
方法三:冒泡法排序
# 例如
FileName = ["10.py", "2.py", "8.py", "6.py", "100.py"]
for i in range(len(FileName)): # 第一个和后面每一个做对比
for j in range(i+1,len(FileName)):
before = int(FileName[i].strip('.py'))
after = int(FileName[j].strip('.py'))
if before > after:
FileName[i], FileName[j] = FileName[j], FileName[i] # 前一个与后一个对比,如果前大于后,则两者互换位置
print(FileName)
# 终端显示
['2.py', '6.py', '8.py', '10.py', '100.py']
python是弱类型语言,对于类型标注只是建议,不是强制要求;
# 例如
def func(a:int, b:int): # 建议a是整数,建议b是整数
print(a + b)
List[int]:建议列表,且元素为整数;
Tuple[int, str]:建议元组,且第一个元素为整数,第二个元素是字符串;
Dict[str, int]:建议字典,键时字符串,值是整数;
Set[str]:建议集合,且元素为字符串;
from typing import Callback # Callback指可调用函数
注意: 传任何数据都是传本身
# 例如
def func(b):
print(id(a), a) # 由于作用域的关系,此处a与外面a的值一样
print(id(b), b)
a = 999
func(a)
# 在交互式页面显示
2443279670768 999 # 两者地址一样,说明是指向同一个地方
2443279670768 999
# 例如
def func(b):
print(id(a), a)
print(id(b), b)
b = 888
print(id(a), a)
print(id(b), b)
a = 999
func(a)
# 在交互式页面显示
2443279670704 999
2443279670704 999
2443279670704 999
2443279671152 888 # 第二个b的地址改变,原地址从引用次数2变成引用次数1
# 例如
def func(b):
print(id(a), a)
print(id(b), b)
b = [999, 888, 777]
print(id(a), a)
print(id(b), b)
a = [999, 777]
func(a)
# 终端显示
2443279865536 [999, 777]
2443279865536 [999, 777] # 类似于加了一步a = b,依旧指向同一个地址
2443279865536 [999, 777]
2443279867648 [999, 888, 777] # 此时b的地址变了,指向了新的地址,a不变
# 例如
def func(b):
print(id(a), a)
print(id(b), b)
b.insert(1, 888)
print(id(a), a)
print(id(b), b)
a = [999, 777]
func(a)
# 在交互式页面显示
2443249410240 [999, 777]
2443249410240 [999, 777]
2443249410240 [999, 888, 777] # inplace操作改变原数据,因此两个都发生变化
2443249410240 [999, 888, 777]
必需参数(形参),也叫位置参数,指对号入座,一个数一个坑,位置不允许变;
# 例如
def test1(a, b):
print(a-b)
test1(1, 2)
test1(2, 1)
# 终端显示
-1 # 顺序改变,结果改变
1
关键字参数(实参):可以不按照位置顺序传,不能放在位置参数前面;
# 例如
def test1(a, b, c):
print(a-b+c)
test1(1, 3, 2)
test1(1, c=2, b=3)
# 终端显示
0
0
注意:
# def test1(a, b, c):
print(a-b+c)
test1(1, 2, b=3)
# 终端显示
TypeError: test1() got multiple values for argument 'b'
# 此时会报错,因为按照位置参数,b=2,然后关键字参数,b=3,此时b接收两个值,因此报错;
默认参数(形参定义):不能放在位置参数前面,不能写在不定长参数**kwargs后面;
# 例如
def test1(a, b, c=5):
print(a-b+c)
test1(1, c=2, b=3)
test1(1, 2)
# 终端显示
0 # 传c的时候,c是实参
4 # 不传c的时候,c默认为5
(*args):形参,一个*号,表示将参数打包成元组,如果不传参数,则会产生空元祖,一个*号的不定长参数后面的必须参数需要用关键字参数传;
# 例如
def test1(a, b, *c): # 不定长参数在位置参数后面
print(a, b, c)
test1(1, 2, 3, 4)
test1(1, 2)
def test2(a, *b, c): # 不定长参数在位置参数前面时,后面的需要用关键字参数上传
print(a, b, c)
test2(1, 2, 3, c=4)
# 终端显示
1 2 (3, 4)
1 2 () # 不传时,默认空元祖
1 (2, 3) 4
(**kwargs):形参,两个**号,表示将参数打包成字典,实参必须是关键字参数,只能放在最后;
# 例如
def test1(a, b, **c):
print(a, b, c)
test1(1, 2, d = 1, e = 2)
test1(1, 2)
test1(1, d = 3, e = 4, b = 5) # b指定参数5,不算不定长参数,不定长参数后面的位置参数要用关键字参数;
# 终端显示
1 2 {'d': 1, 'e': 2}
1 2 {} # 不传时默认空字典
1 5 {'d': 3, 'e': 4}
不需要传任何实参
/:前面只能用位置参数
*:后面只能用关键字参数
# 例如
def test1(a, b, /, c, *, d):
print(a, b, c, d)
test1(1, 2, 3, d= 4)
# 终端显示
1 2 3 4
注意:
匿名函数是一个表达式,可以被接收,比较灵活;
格式:lambda arg1, arg2, arg3:表达式
,最后,会返回表达式;
匿名函数后面的表达式只能接一个;
可以作为参数传到其他函数里;
可以不传参数;
匿名函数可以放到匿名函数里面去;
# 例如
test1 = lambda a, b, c:a+b+c
print(test1(1, 2, 3))
print('-------------------------')
test2 = lambda a, b, c:print(a+b+c)
print(test2(1, 2, 3))
print('-------------------------')
test3 = lambda : '啥也没有'
def fun(func):
print(func()) # 运行func(),即运行test(),返回'啥也没有'
fun(test3) # func = test3,此处是引用,无返回值
print('-------------------------')
test4 = lambda a, b, c: a+b+c
def fun1(func1, a, b, c):
print(func1(a, b, c)) # 运行test4(1,2,3)
fun1(test4, 1, 2, 3) # 按位置上传参数,func1=test4,a=1,b=2,c=3
print('-------------------------')
test5 = lambda fun2, a, b, c: fun2(a, b, c)
# fun2 = lambda a, b, c: a+b+c
print(test5(lambda a, b, c: a+b+c,1,2,3)) # 调用的第一个函数就是已经注释的匿名函数fun2
# 终端显示
6
-------------------------
6
None
-------------------------
啥也没有
-------------------------
6
-------------------------
6
将多个值赋给一个函数的时候,会自动将多个值封包成一个元组;
# 例如
a = 1, 2, 3, 4
print(a)
# 终端显示
(1, 2, 3, 4)
可迭代对象都支持解包;
一个*号表示将一个变量可以接受多个值,以列表形式
两个**号表示,解包为关键字参数,只能对字典进行;
但是字典前带一个*号表示对该字典的键进行解包;
式子中不允许多个*存在;
基础用法:
# 例如
a , b, c, d= 1, 2, 3, 4
print(a , b, c, d)
print('-------------1------------------')
# a , b, c= 1, 2, 3, 4
# print(a , b, c) #当等式左右两边数量不一致,会报错
print('-------------2------------------')
a , b, *c= 1, 2, 3, 4 # 对元素带上*号,表示可以对这个元素进行多个赋值,多余的元素都打包给他,返回列表
print(a , b, c)
print('-------------3------------------')
a , *b, c= 1, 2, 3, 4 #注意,此处与*arg不同,封包会先考虑其他元素有没有赋值,如果其他元素都已经赋值,则将其他元素统一打包给他;
print(a , b, c)
print('-------------4------------------')
a , *b, f, e, c= 1, 2, 3, 4 # 甚至说其他元素都赋完值之后,没有元素给他了,*b也可以为空列表
print(a , b, f, e, c)
print('-------------5------------------')
*a, = 1, 2, 3, 4 # 当只有一个带*号的值的时候,要带,号,因为封包会成为元组,然后解包成为列表
print(a)
print('-------------6------------------')
lis1 = [1, 2, 3, 4] # 对可迭代对象解包,会将可迭代对象自动解包为元素个数
print(*lis1)
print('-------------7------------------')
def func(a):
print(a)
dict1 = {'a':2}
func(**dict1) # 对字典进行解包成关键字参数,然后通过func调用,此时关键字参数a = 2传入func()中;
# 终端显示
1 2 3 4
-------------1------------------
ValueError: too many values to unpack (expected 3)
-------------2------------------
1 2 [3, 4]
-------------3------------------
1 [2, 3] 4
-------------4------------------
1 [] 2 3 4
-------------5------------------
[1, 2, 3, 4]
-------------6------------------
1 2 3 4
-------------7------------------
2
疑难杂症:
# 例如
def func(*arg):
print(*arg)
print(arg)
lis = [1, 2, 3]
func(lis)
func(*lis)
# 终端显示
[1, 2, 3] # 将列表lis作为整体传入func(*arg)中,此时列表作为作为一整个不定长参数,封包此时格式为([1, 2, 3],),然后Print(*arg)在调用过程中,对arg(也就是([1, 2, 3],))进行解包,元组中只有一个元素,因此解包为一个列表
([1, 2, 3],) # 将列表lis作为整体传入func(*arg)中,此时列表作为作为一整个不定长参数,封包此时格式为([1, 2, 3],),然后print(arg)在调用过程中,没有对([1, 2, 3],)进行解包,直接输出,故输出一个列表
1 2 3 # 将列表lis先解包,成为对应的三个元素1,2,3,然后在调用func(*arg)中,将三个元素打包成元组传给不定长参数*arg,此时形式是(1,2,3),然后在输出print(*arg)过程中,对其进行解包,可迭代对象解包成元素个数个元素,因此输出1,2,3
(1, 2, 3) # # 将列表lis先解包,成为对应的三个元素1,2,3,然后在调用func(*arg)中,将三个元素打包成元组传给不定长参数*arg,此时形式是(1,2,3),然后在输出print(arg)过程中,直接输出,没有解包,因此输出(1,2,3)
# 例如
*a, b, c = [1,2,3,4]
print(*a)
print('-------------1------------------')
def func(b=4,**a):
print(*b,a)
a = {'a':2}
func(a,**a)
# 终端显示
1 2 #先解包,1和2解包成为列表[1,2],然后在输出的时候再次解包
-------------1------------------
a {'a': 2} # 显示传a,因为上传了实参,所以b=4无效,*b相当于*{'a':2},于是等价于'a';
# 上传的时候对a进行解包成关键字参数,然后在调用过程中,上传不定长参数的时候对关键字参数重新打包成为字典,并输出;