一. python的几种入参形式:
1.普通参数:
普通参数就是最一般的参数传递形式。函数定义处会定义需要的形参,然后函数调用处,需要与形参一一对应地传入实参。
示例:
1 def f(a, b):
2 print(a,b)
3 f(1, 2)
2. 指定参数:
指定参数就是在函数调用时,给传入的实参加上其对应的形参的参数名,这样实参的顺序就可以不用和形参完全一一对应的顺序。
示例:
1 def f(a, b):
2 print(a, b)
3 f(b=1, a=2)
3. 默认参数:
默认参数是在函数的形参处直接设定好一个参数的值,在函数调用的时候,可以不传入对应这个形参的实参,当不传入参数时,会直接取这个设定的默认值。当传入时,会用传入的值。
此外要注意,有默认值的参数,需要放在所有无默认值的参数之后。
示例:
1 def f (a, b=1, c=2):
2 print(a,b,c)
3 f(1,2)
4. 动态参数:
动态参数就是可以在函数的形参处不指定具体的名称与个数,在函数被调用时,传入的实参皆可在函数中获得。
动态参数有两种形式,一种以列表的形式,一种以字典的形式。
(1) 当以列表形式的时候,在函数调用时,实参的传递与普通的方式类似,直接传入;形参获取到的是一个列表的形式,元素为传入的每个实参。
示例:
1 def f(*args):
2 for i in args:
3 print(i)
4 f(1,23,3)
(2) 当以字典形式时,在函数调用时,实参传递类似制定参数的方式;形参获得的是一个字典。
示例:
1 def f(**kargs):
2 for k, v in kargs.items():
3 print(k, v)
4 f(k1=1, k2=2)
(3) 此外两种形式也可以一起使用,并且也可以和其他类型如普通参数,有默认值的参数一起使用。
此外需要注意的是,列表形式的动态参数需要放在普通参数和默认值参数之后,字典形式的动态参数,需要放在所有类型的参数之后。
示例:
1 def f(a, b=1, *args, **kargs):
2 print(a,b)
3 for i in args:
4 print(i)
5 for k, v in kargs.items():
6 print(k, v)
7 f(1,2,22,33,k1=4,k2=5)
(4) 另外还有种向函数传递默认参数的方法,即在函数调用时,在传入的列表前加*,在传入的字典前加**,这样被传入的参数就不会被当做是一整个列表或字典,而是动态参数。
示例:
1 a = [1,2]
2 k = {'k1':1, 'k2':2}
3 def f(*args, **kargs):
4 for i in args:
5 print(i)
6 for k, v in kargs.items():
7 print(k, v)
8 f(*a, **k)
二. python参数的引用传递
虽然python中并没有类似C语言中的显示支指出传递参数还是引用或者指针这种类似设计,但实际上,当python函数的入参是list, tuple, dict, set, deque等容器时候,传入的其实是引用即其本身,而非复制的结果。
在函数内部修改这些入参后,操作的即传入的实参的内存,所以即使出了函数外部,实参也被改变了。
(1)传入list的示例:
(2)传入dict的示例:
(3)传入set的示例:
(4)另外需要注意的是,如果在函数内部,将传入的容器类参数做一个重新赋值,那么当出了函数以后,原版的实参值并不变。这是因为在函数内部赋值,其实把函数的形参指向了一块新的内存,原本的容器值并没有改变,等到出了作用域,自然会发现值没变。示例:
三. set的常用方法与时间复杂度
set是一个无需不重复的元素集合,此外与list和tuple的主要区别是,支持方便直接地做一些集合运算,如:
并集、交集、差集、判断是否子集、判断是否父集。当然也支持增加与删除元素等操作。
时间复杂度如下: