第五课:改变函数参数的值
一个python函数可以有任意多个参数,在一个函数的外部来定义变量,然后把变量作为参数传入到函数内,并且在函数的内部来修改函数的参数值,函数结束之后,这些变量的值在如何变化呢?
给函数传递值有2种:1种是值传递,1种是引用传递
# 改变函数参数的值
# 值传递(数值、字符串、布尔 这些都是值传递) 在函数的内部修改变量值,不改变原参数定义的参数值,解释为: 这个在函数中不会改变原来定义(函数外部)的值 这是因为函数里面会有一个占的概念,外边的变量的值会复制给 占 里面,对于 函数中的变量来说 并不是指的是同一个变量 在函数里修改的参数的变量的值其实是修改了函数的一个副本,和外边的参数没有直接关系
# 引用传递(复合类型,列表、字典、以后要讲的对象) 在函数的内部修改变量值,将会改变原参数定义的参数值, 具体的解释为: 这个在函数中会改变原来定义(函数外部)的值 这里的引用和c语言的指针比较类似
x = 100
s = 'hello world'
def test1(xx,ss): # 将这2个变量变成参数传给 函数test1
xx = 200
ss = 'I love you.'
test1(x,s) # 这一步是讲外边的定义的变量传给函数
print(x, s) # 结果为 100 hello world 值没有变化 还是和外边定义的变量值是一样的 这是因为 x s 都是值传递
-------
复杂的类型
numList = [1,2,3,4,5]
numDict = {'a':1, 'b':2, 'c':3}
a = numList
a[1] = 4
print(numList) # [1, 4, 3, 4, 5] 这一步是将numList的引用复制了一份给了a 那么这样的numList 和 a 他们的引用(指针) 指向同一个地址空间,如果我们修改了a的值numList的值也就被修改了 这里的变量是存储了列表和字典的引用 ;其实光看这个引用的话,其实就是把这个列表和字典的引用传给函数中的值 在函数体内,所用的内存空间和外部的是一样的,所以值就会根据函数体内的值的改变而改变。
def test2(nl,nd):
nl[2] = 1234
nd['c'] = 4321
test2(numList, numDict) # 函数传参
print(numList) # [1, 4, 1234, 4, 5]
print(numDict) # {'a': 1, 'b': 2, 'c': 4321}
# 我们发现这里的输出的值,改变了原先定义的列表和字典 这里叫做 引用传递
输出的结果为:
100 hello world // 这个结果和原来定义的没变
[1, 4, 3, 4, 5] // 这里类似于 引用 (指针),值是会改变的
[1, 4, 1234, 4, 5]
{'a': 1, 'b': 2, 'c': 4321}
-------------------------------------------------------------------
第六课:改变函数参数的值(案例) // 这个例子很牛逼
在 控制台输入一些数据,以逗号分隔的字符串 , 然后把这些数据转化为字典或者序列
# 从控制台输入一些数据(以逗号分隔的字符串),然后保存到一个大的字典中 首先先用普通的方法实现,然后将一部分的代码抽象处理,然后再用函数去实现 我们就是用复合类型的数据,将字典传入函数,然后在函数的内部 修改字典的值,当函数结束的时候,保留在函数内部修改的效果
data = {} # 首先定义个字典
data['d'] = {} # d的放在字典
data['names'] = [] # names放在列表中
print('请输入字典数据,key和value之间用逗号分隔') # 从控制台输入
dictStr = input(':') # 从控制台输入
# 比如:我们输入
# a,b,c,d
# {'a':'b','c':'d'}
list = dictStr.split(',') # 利用逗号进行分割
keys =[] # key 和 value 都取出来, 奇数的Wie key 偶数为 values
values =[]
for i in range(len(list)):
if i % 2 == 0:
keys.append(list[i])
else:
values.append(list[i])
print(keys) # ['a', 'b', 'c']
print(values) # ['1', '2', '3']
for values in zip(keys,values): # 将第一个列表的第一个元组值转化为 元组
print(values)
'''
('a', '1')
('b', '2')
('c', '3')
'''
输出的结果为:
请输入字典数据,key和value之间用逗号分隔
:a,1,b,2,c,3
['a', 'b', 'c']
['1', '2', '3']
('a', '1')
('b', '2')
('c', '3')
-----------------------------
第二种方法:
data = {}
data['d'] = {}
data['names'] = []
print('请输入字典数据,key和value之间用逗号分隔')
dictStr = input(':')
# a,b,c,d
# {'a':'b','c':'d'}
list = dictStr.split(',') # 分隔符为 ,
keys =[]
values =[]
for i in range(len(list)):
if i % 2 == 0: # 偶数 分割 true为 key false为 values
keys.append(list[i])
else:
values.append(list[i])
data['d'].update(dict(zip(keys,values))) # 这一步的意思是 把元组转化为字典 更新到d这个字典后面
print('请输入姓名,多个姓名之间用逗号分隔')
nameStr = input(':')
names = nameStr.split(',')
data['names'].extend(names) # 把另外一个列表追加到一个列表的后面
print(data)
输出的结果为:
请输入字典数据,key和value之间用逗号分隔
:a,1,b,2,c,3
请输入姓名,多个姓名之间用逗号分隔
:majihui,zhaoshun
{'d': {'a': '1', 'b': '2', 'c': '3'}, 'names': ['majihui', 'zhaoshun']}
如果我们有多个data这样的字典,难道我们的代码要复制10份吗,下面引入 函数 :我们把代码进行抽象,放在一个函数里面 对重复使用的代码。
第三种方法:函数的方法
# 从控制台输入一些数据(以逗号分隔的字符串),然后保存到一个大的字典中
# 1. 初始化字典data
# 2. 从控制台输入以逗号分隔的字符串,并将其转换为列表或字典
# 3. 输出字典data
# 1. 初始化字典data
def init(data):
data['d'] = {}
data['names'] = []
# 2. 从控制台输入以逗号分隔的字符串,并将其转换为列表或字典
# True:转换为列表,False:转换为字典
def inputListOrDict(flag,msg):
print(msg)
inputStr = input(':')
list = inputStr.split(',')
# 直接返回列表
if flag:
return list
keys =[]
values =[]
result = {}
for i in range(len(list)):
if i % 2 == 0:
keys.append(list[i])
else:
values.append(list[i])
return dict(zip(keys,values))
# 3. 输出字典data
def outDict(data):
for key in data.keys():
print(key, ':', data[key])
// 把上面这3个 函数 封装成一个模块 dataman 我们要维护代码的话,就只需要维护下面这几个 就可以了
from dataman import *
data1 = {}
data2 = {}
init(data1)
init(data2)
data1['d'].update(inputListOrDict(False, '请输入字典数据'))
data1['names'].extend(inputListOrDict(True, '请输入列表数据'))
data2['d'].update(inputListOrDict(False, '请输入字典数据'))
data2['names'].extend(inputListOrDict(True, '请输入列表数据'))
outDict(data1)
outDict(data2)
--------------------------------------------------------
课程七:函数中关键字参数和参数默认值
# 关键字参数和参数默认值
# 位置参数 中 形参 值参
# 混合使用位置参数和关键字参数 需要注意点
# 1. 关键字参数必须跟在位置参数后面
# 2. 同一个形参不能同时使用位置参数和关键字参数赋值
# 函数参数默认值,如果一个参数有默认值,那么该参数后面的所有的参数必须都有默认值,否则会抛出异常
def greet(name, greeting): # 函数里面有参数 一个参数叫name 一个参数叫 greeting 这2个叫形参
return '问候语:{} 姓名:{}'.format(greeting, name)
print(greet('李宁', 'Hello')) # 问候语:Hello 姓名:李宁 这里的 Hello 李宁 就表示的值参
print(greet('Hello', '李宁')) # 问候语:李宁 姓名:Hello
# 解决参数的调用方式,解决参数的代码的语言 通俗的讲 就是解决调用的参数的时候,能一下子让人看的懂
# 关键字参数 可以不按照形参的输入顺序 本讲的主要内容
print(greet(name='李宁',greeting='Hello')) # 关键字的参数就是形参的名字 在函数的内部和外部都可以使用,内部就是形参 外部就是一个变量
print(greet(greeting = 'Hello', name='李宁'))
print(greet('Bill', greeting='Hello')) # 关键字参数和位置参数混合使用 生产上建议用关键字参数,让人一看代码就明白
# print(greet(name='Mike', 'Hello')) # 这个会报错 不行 为什么呢?
# 混合使用位置参数和关键字参数 需要注意点
# 1. 关键字参数必须跟在位置参数后面
# 2. 同一个形参不能同时使用位置参数和关键字参数赋值
# print(greet('Bill', name='Hello'))
def fun(a,b,c = 123,d=4,e=12,f =20,g=40): # 函数参数默认值,如果一个参数有默认值,那么该参数后面的所有的参数必须都有默认值,否则会抛出异常
print(a,b,c,d,e,f,g)
fun(1,2,3,4,5) # 1 2 3 4 5 20 40
----------------------------------------------------------------------
第八课:函数中可变参数
// 什么是可变参数?
任意传输参数值是可变的,传输的参数的个数是不定的 可变参数的可变是表示参数的个数是可以变化的
如何在一个函数中,定义可变参数
# 可变参数
# print(1,2,3,4,5,7,'a')
# 可变参数在函数内部的表现形式是一个元组
# 一般情况下,可变参数需要放在普通参数后面
# 如果可变参数后面还有普通参数,如果普通参数没有默认值,为普通参数传值
# 必须要使用关键字参数形式,如果有默认值,可以不传值
def printParams(*params): # 在函数中定义一个可变参数,需要在 参数的前面加一个* 就成为 可变参数
print(params)
printParams("hello", 1,True) # ('hello', 1, True) 表现形式是一个元组 这里面的参数可以随便的调整,
def printParams1(*params):
for param in params: # 对每一个元组进行了for循环的迭代
print('<' + str(param) + '>', end = ' ') # 需要提前转化为字符串 因为有可以输入的是数值,数值不可以和字符串直接相加
printParams1('hello',1,2,3,False,40.1) # <1> <2> <3> <40.1> 我们得到了每一个值
print()
def printParams2(value, *params): # 一般情况下,把可变参数放到 普通参数后面 也有不一般的情况下 后面讲
print('[' + str(value) + ']')
for param in params:
print('<' + str(param) + '>', end = ' ')
printParams2('hello',1,2,3,4)
# [hello]
# <1> <2> <3> <4>
#def printParams3(value1, *params, value2 = 20, value3=30): 解决方法1 在定义函数的时候加上默认值
def printParams3(value1, *params, value2, value3):
print('[' + str(value1) + ']')
print('[' + str(value2) + ']')
print('[' + str(value3) + ']')
for param in params:
print('<' + str(param) + '>', end = ' ')
printParams3('hello',1,2,3,4,5,value2 = 100, value3 = 200) # 解决方法2 在输出的时候,加上关键字参数
--------------------------------------------------------------------
第九课:将序列中的元素值作为函数对应的参数值传递
# 将序列作为函数的参数值 并不是将一个序列看成一个整体,传入函数的一个参数;而是将这个序列拆开,将每一个序列的元数值作为一个单独的参数传入函数的参数。
def printParams1(s1, s2):
print(s1, s2)
printParams1("Hello", "World")
strList = ['Hello', 'World']
printParams1(*strList) # 把列表前面加一个* 就会把列表中的参数的值拆开 到函数的每一个参数中 最后的值为: Hello World
def printParams2(*ss): # 定义成可变参数,也是可以的
for s in ss:
print('<{}>'.format(s), end = ' ')
printParams2(*strList) #
print()
printParams2(*'abcdefg') # 直接传值
print()
printParams2(*[1,2,3,4,5,6]) # <1> <2> <3> <4> <5> <6> 他会自动的把列表的值拆开 作为可变参数传入
def printParams3(**ss): # 如何我们传入字典呢? 传入字典需要2 个 **
for item in ss.items(): # 这里用 items 方法输入 key value
print(item) # 变量输出 表现形式为 元组
print('{} = {}'.format(item[0], item[1]))
dict = {'a':10, 'b':20,'c':30}
printParams3(**dict)
printParams3(**{'name':'Bill','age':20})
'''
a = 10
('b', 20)
b = 20
('c', 30)
c = 30
('name', 'Bill')
name = Bill
('age', 20)
age = 20
'''
# 这个是不加2个** 和加2个** 是没有本质的区别的 我操
def printParams4(ss):
for item in ss.items():
print(item)
print('{} = {}'.format(item[0], item[1]))
dict = {'a':10, 'b':20,'c':30}
printParams4(dict)
printParams4({'name':'Bill','age':20})
注意:
为函数传递可变参数值(单星和双星参数)
单星和双星 参数 : 都是作为扩展参数用的 区别是什么呢?
*a # 导入元组和列表的
**a # 导入字典的
def f1(a1,*a2):
print(a1)
print(a2)
f1(1,2,3,4,5)
输出结果
1
(2, 3, 4, 5)
def f2(a1,**a2):
print(a1)
print(a2)
f2(1,aaa=111,bbb=222)
输出的结果为:
1
{'aaa': 111, 'bbb': 222}
#就会自动的把后面关键字参数转化为字典输出