函数定义时括弧内为形参,一个函数可以没有形参,但是括弧必须要有,表示该函数不接受参数
函数调用时,将实参的引用传递给形参
在定义函数时,对参数个数并没有限制,如果有多个形参,需要使用逗号进行分隔
对于绝大多数情况下,在函数内部直接修改形参的值不会影响实参,而是创建一个新变量。
>>> def addOne(a):
print(id(a), ':', a)
a += 1
print(id(a), ':', a)
>>> v = 3
>>> id(v)
1599055008
>>> addOne(v)
1599055008 : 3
1599055040 : 4
>>> v
3
>>> id(v)
1599055008
>>> def modify(v): # 使用下标修改列表元素值
v[0] = v[0]+1
>>> a = [2]
>>> modify(a)
>>> a
[3]
>>> def modify(v, item): # 使用列表的方法为列表增加元素
v.append(item)
>>> a = [2]
>>> modify(a,3)
>>> a
[2, 3]
>>> def modify(d): #修改字典元素值或为字典增加元素
d['age'] = 38
>>> a = {'name':'Dong', 'age':37, 'sex':'Male'}
>>> a
{'age': 37, 'name': 'Dong', 'sex': 'Male'}
>>> modify(a)
>>> a
{'age': 38, 'name': 'Dong', 'sex': 'Male'}
>>> def demo(a, b, c):
print(a, b, c)
>>> demo(3, 4, 5) #按位置传递参数
3 4 5
>>> demo(3, 5, 4)
3 5 4
>>> demo(1, 2, 3, 4) #实参与形参数量必须相同
TypeError: demo() takes 3 positional arguments but 4 were given
>>> def say(message, times=1 ):
print(message*times)
>>> say('hello')
hello
>>> say('hello',3)
hello hello hello
>>> say('hi',7)
hi hi hi hi hi hi hi
>>> def join(lst, sep=None):
return (sep or ' ').join(lst)
>>> aList = ['a', 'b', 'c']
>>> join(aList)
'a b c'
>>> join(aList, ',')
'a,b,c'
>>> def func(a=3, b, c=5): # 失败,带默认值的参数后面有不带默认值的参数
print(a, b, c)
SyntaxError: non-default argument follows default argument
>>> def func(a=3, b): # 失败,带默认值的参数后面有不带默认值的参数
print(a, b)
SyntaxError: non-default argument follows default argument
>>> def func(a, b, c=5): # 成功
print(a, b, c)
def demo(newitem,old_list=[]):
old_list.append(newitem)
return old_list
print(demo('5',[1,2,3,4]))
print(demo('aaa',['a','b']))
print(demo('a'))
print(demo('b'))
[1, 2, 3, 4, '5']
['a', 'b', 'aaa']
['a']
['a', 'b']
def demo(newitem,old_list=None):
if old_list is None:
old_list=[]
new_list = old_list[:]
new_list.append(newitem)
return new_list
print(demo('5',[1,2,3,4]))
print(demo('aaa',['a','b']))
print(demo('a'))
print(demo('b'))
>>> def demo(a,b,c=5):
print(a,b,c)
>>> demo(3,7)
3 7 5
>>> demo(a=7,b=3,c=6)
7 3 6
>>> demo(c=8,a=9,b=0)
9 0 8
>>> def demo(*p):
print(p)
>>> demo(1,2,3)
(1, 2, 3)
>>> demo(1,2)
(1, 2)
>>> demo(1,2,3,4,5,6,7)
(1, 2, 3, 4, 5, 6, 7)
>>> def demo(*p):
print(p)
>>> demo(1,2,3)
(1, 2, 3)
>>> demo(1,2)
(1, 2)
>>> demo(1,2,3,4,5,6,7)
(1, 2, 3, 4, 5, 6, 7)
>>> def func_4(a, b, c=4, *aa, **bb):
print(a,b,c)
print(aa)
print(bb)
>>> func_4(1,2,3,4,5,6,7,8,9,xx='1',yy='2',zz=3)
1 2 3
(4, 5, 6, 7, 8, 9)
{'xx': '1', 'yy': '2', 'zz': 3}
>>> func_4(1,2,3,4,5,6,7,xx='1',yy='2',zz=3)
1 2 3
(4, 5, 6, 7)
{'xx': '1', 'yy': '2', 'zz': 3}
>>> def demo(a, b, c):
print(a+b+c)
>>> seq = [1, 2, 3]
>>> demo(*seq)
6
>>> tup = (1, 2, 3)
>>> demo(*tup)
6
>>> dic = {1:'a', 2:'b', 3:'c'}
>>> demo(*dic)
6
>>> Set = {1, 2, 3}
>>> demo(*Set)
6
>>> demo(*dic.values())
abc
>>> def demo(a, b, c):
print(a+b+c)
>>> dic = {'a':1, 'b':2, 'c':3}
>>> demo(**dic)
6
>>> demo(a=1, b=2, c=3)
6
>>> demo(*dic.values())
6
>>> def demo(a, b, c): #定义函数
print(a, b, c)
>>> demo(*(1, 2, 3)) #调用,序列解包
1 2 3
>>> demo(1, *(2, 3)) #位置参数和序列解包同时使用
1 2 3
>>> demo(1, *(2,), 3)
1 2 3
>>> demo(a=1, *(2, 3)) #序列解包相当于位置参数,优先处理
Traceback (most recent call last):
File "" , line 1, in <module>
demo(a=1, *(2, 3))
TypeError: demo() got multiple values for argument 'a'
>>> demo(b=1, *(2, 3))
Traceback (most recent call last):
File "" , line 1, in <module>
demo(b=1, *(2, 3))
TypeError: demo() got multiple values for argument 'b'
>>> demo(c=1, *(2, 3))
2 3 1
>>> demo(**{'a':1, 'b':2}, *(3,)) #序列解包不能在关键参数解包之后
SyntaxError: iterable argument unpacking follows keyword argument unpacking
>>> demo(*(3,), **{'a':1, 'b':2})
Traceback (most recent call last):
File "" , line 1, in <module>
demo(*(3,), **{'a':1, 'b':2})
TypeError: demo() got multiple values for argument 'a'
>>> demo(*(3,), **{'c':1, 'b':2})
3 2 1
>>> a_list = [1, 2, 3, 4, 9, 5, 7]
>>> print(sorted(a_list))
[1, 2, 3, 4, 5, 7, 9]
>>> print(a_list)
[1, 2, 3, 4, 9, 5, 7]
>>> print(a_list.sort())
None
>>> print(a_list)
[1, 2, 3, 4, 5, 7, 9]
全局变量可以通过关键字global来定义。这分为两种情况
>>> def demo():
global x
x = 3
y = 4
print(x,y)
>>> x = 5
>>> demo()
3 4
>>> x
3
>>> y
NameError: name 'y' is not defined
>>> del x
>>> x
NameError: name 'x' is not defined
>>> demo()
3 4
>>> x
3
>>> y
NameError: name 'y' is not defined
>>> x = 3
>>> def f():
print(x) #本意是先输出全局变量x的值,但是不允许这样做
x = 5 #有赋值操作,因此在整个作用域内x都是局部变量
print(x)
>>> f()
Traceback (most recent call last):
File "" , line 1, in <module>
f()
File "" , line 2, in f
print(x)
UnboundLocalError: local variable 'x' referenced before assignment
>>> def demo():
x = 3 #创建了局部变量,并自动隐藏了同名的全局变量
>>> x = 5
>>> x
5
>>> demo()
>>> x #函数执行不影响外面全局变量的值
5
def scope_test():
def do_local():
spam = "我是局部变量"
def do_nonlocal():
nonlocal spam # 这时要求spam必须是已存在的变量
spam = "我不是局部变量,也不是全局变量"
def do_global():
global spam # 如果全局作用域内没有spam,就自动新建一个
spam = "我是全局变量"
spam = "原来的值"
do_local()
print("局部变量赋值后:", spam) # 原来的值
do_nonlocal()
print("nonlocal变量赋值后:", spam) # 我不是局部变量,也不是全局变量
do_global()
print("全局变量赋值后:", spam) # 我不是局部变量,也不是全局变量
scope_test()
print("全局变量:", spam) # 我是全局变量
>>> f = lambda x, y, z: x+y+z #可以给lambda表达式起名字
>>> f(1,2,3) #像函数一样调用
6
>>> g = lambda x, y=2, z=3: x+y+z #参数默认值
>>> g(1)
6
>>> g(2, z=4, y=5) #关键参数
11
>>> L = [(lambda x: x**2), #匿名函数
(lambda x: x**3),
(lambda x: x**4)]
>>> print(L[0](2),L[1](2),L[2](2)) #调用lambda表达式
4 8 16
>>> D = {'f1':(lambda:2+3), 'f2':(lambda:2*3), 'f3':(lambda:2**3)}
>>> print(D['f1'](), D['f2'](), D['f3']())
5 6 8
>>> L = [1,2,3,4,5]
>>> print(list(map(lambda x: x+10, L))) #lambda表达式作为函数参数
[11, 12, 13, 14, 15]
>>> L
[1, 2, 3, 4, 5]
>>> def demo(n):
return n*n
>>> demo(5)
25
>>> a_list = [1,2,3,4,5]
>>> list(map(lambda x: demo(x), a_list)) #在lambda表达式中调用函数
#等价于list(map(demo, a_list))
[1, 4, 9, 16, 25]
>>> data = list(range(20)) #创建列表
>>> data
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> import random
>>> random.shuffle(data) #打乱顺序
>>> data
[4, 3, 11, 13, 12, 15, 9, 2, 10, 6, 19, 18, 14, 8, 0, 7, 5, 17, 1, 16]
>>> data.sort(key=lambda x: x) #和不指定规则效果一样
>>> data
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
>>> data.sort(key=lambda x: len(str(x))) #按转换成字符串以后的长度排序
>>> data
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> data.sort(key=lambda x: len(str(x)), reverse=True)
#降序排序
>>> data
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> import random
>>> x = [[random.randint(1,10) for j in range(5)] for i in range(5)]
#包含5个子列表的列表
#每个子列表中包含5个1到10之间的随机数
>>> for item in x:
print(item)
[5, 6, 8, 7, 4]
[1, 5, 3, 9, 4]
[9, 6, 10, 7, 6]
[8, 2, 7, 1, 6]
[1, 7, 5, 3, 5]
>>> y = sorted(x, key=lambda item: (item[1], item[4]))
#按子列表中第2个元素升序、第5个元素升序排序
>>> for item in y:
print(item)
[8, 2, 7, 1, 6]
[1, 5, 3, 9, 4]
[5, 6, 8, 7, 4]
[9, 6, 10, 7, 6]
[1, 7, 5, 3, 5]
>>> list(map(str,range(5)))
['0', '1', '2', '3', '4']
>>> def add5(v):
return v+5
>>> list(map(add5,range(10)))
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
>>> def add(x, y):return x+y
>>> list(map(add, range(5), range(5)))
[0, 2, 4, 6, 8]
>>> from functools import reduce
>>> seq=[1,2,3,4,5,6,7,8,9]
>>> reduce(lambda x,y:x+y, seq)
45
>>> def add(x, y):
return x + y
>>> reduce(add,range(10))
45
>>> reduce(add,map(str,range(10)))
'0123456789'
>>> seq=['foo','x41','?!','***']
>>> def func(x):
return x.isalnum()
>>> list(filter(func,seq))
['foo', 'x41']
>>> seq
['foo', 'x41', '?!', '***']
>>> [x for x in seq if x.isalnum()]
['foo', 'x41']
>>> list(filter(lambda x:x.isalnum(),seq))
['foo', 'x41']
>>> def f():
a, b = 1, 1 #序列解包,同时为多个元素赋值
while True:
yield a #暂停执行,需要时再产生一个新元素
a, b = b, a+b #序列解包,继续生成新元素
>>> a = f() #创建生成器对象
>>> for i in range(10): #斐波那契数列中前10个元素
print(a.__next__(), end=' ')
1 1 2 3 5 8 13 21 34 55
>>> for i in f(): #斐波那契数列中第一个大于100的元素
if i > 100:
print(i, end=' ')
break
144
>>> a = f() #创建生成器对象
>>> next(a) #使用内置函数next()获取生成器对象中的元素
1
>>> next(a) #每次索取新元素时,由yield语句生成
1
>>> a.__next__() #也可以调用生成器对象的__next__()方法
2
>>> a.__next__()
3