【漫漫转码路】Python Day 12

一、解题

1、删除给定字符串的指定索引元素,并返回新的字符串

方法一:切片拼接

# 例如
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

2、对于给定列表元素按数字排序

方法一:用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]

四、参数类型

1、必需参数

必需参数(形参),也叫位置参数,指对号入座,一个数一个坑,位置不允许变;

# 例如
def test1(a, b):
    print(a-b)
test1(1, 2)
test1(2, 1)
# 终端显示
-1  # 顺序改变,结果改变
1

2、关键字参数

关键字参数(实参):可以不按照位置顺序传,不能放在位置参数前面;

# 例如
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接收两个值,因此报错;

3、默认参数

默认参数(形参定义):不能放在位置参数前面,不能写在不定长参数**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

4、不定长参数

(*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}

5、特殊参数

不需要传任何实参
/:前面只能用位置参数
*:后面只能用关键字参数

# 例如
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

六、封包 / 解包

1、封包

将多个值赋给一个函数的时候,会自动将多个值封包成一个元组;

# 例如
a = 1, 2, 3, 4
print(a)
# 终端显示
(1, 2, 3, 4)

2、解包

可迭代对象都支持解包;
一个*号表示将一个变量可以接受多个值,以列表形式
两个**号表示,解包为关键字参数,只能对字典进行;
但是字典前带一个*号表示对该字典的键进行解包;
式子中不允许多个*存在;
基础用法:

# 例如 
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进行解包成关键字参数,然后在调用过程中,上传不定长参数的时候对关键字参数重新打包成为字典,并输出;

你可能感兴趣的:(转码,python,开发语言,深度学习,人工智能)