soarli

Python基础语法(函数)
函数返回多个值显然我们不能用多个return实现,不过我们可以在函数中把多个值“打包”再返回。 def test(...
扫描右侧二维码阅读全文
06
2020/02

Python基础语法(函数)

函数返回多个值

显然我们不能用多个return实现,不过我们可以在函数中把多个值“打包”再返回。


def test():
    a = 11
    b = 22
    c = 33


    #打包成列表
    #d = [a,b,c]
    #return d

    #或者
    #return [a,b,c]
    
#运行结果:
#soarli@soarli:~/Desktop$ python3 4.py
#[11, 22, 33]

    #打包成元组
    #return (a,b,c)

    #或者
    return a,b,c

#运行结果:
#soarli@soarli:~/Desktop$ python3 4.py
#(11, 22, 33)


num = test()
print(num)

函数的嵌套调用(小程序:求3个整数的平均值)

def sum_3_nums(a, b, c):
    result = a+b+c
    #print("%d+%d+%d=%d"%(a,b,c,result))
    return result

def average_3_nums(a1, a2, a3):
    result = sum_3_nums(a1, a2, a3)
    result = result/3 #result/=3
    print("平均值是:%d"%result)

#1. 获取3个数值
num1 = int(input("第1个值:"))
num2 = int(input("第2个值:"))
num3 = int(input("第3个值:"))

#sum_3_nums(num1, num2, num3)
average_3_nums(num1, num2, num3)

全局变量、局部变量的区别和使用

  • 全局变量放在调用函数语句之前即可发挥作用,但原则上讲我们应该将其放在定义函数之前。
  • 局部变量与全局变量名字相同时,会默认对局部变量进行操作,除非加上global来声明是对全局变量进行操作。
'''
def get_wendu():
    wendu = 33
    return wendu

def print_wendu(wendu):
    print("温度是%d"%wendu)

result = get_wendu()#如果一个函数有返回值,但是没有在调用函数之前 用个变量保存的话,那么没有任何的意义
print_wendu(result)
'''

#定义一个全局变量,wendu
wendu = 0

def get_wendu():
    #如果wendu这个变量已经在全局变量的位置定义了,此时还想在函数中对这个全局变量进行修改的话
    #那么 仅仅是 wendu=一个值  这还不够,,,此时wendu这个变量是一个局部变量,仅仅是和全局变量的名字
    #相同罢了
    #wendu = 33
    
    #使用global用来对一个全局变量的声明,那么这个函数中的wendu=33就不是定义一个局部变量,而是
    #对全局变量进行修改
    global wendu
    wendu = 33

def print_wendu():
    print("温度是%d"%wendu)

get_wendu()
print_wendu()

将名片管理系统封装成函数形式


#用来存储名片
card_infors = []

def print_menu():
    """完成打印功能菜单"""
    print("="*50)
    print("   名片管理系统 V0.01")
    print(" 1. 添加一个新的名片")
    print(" 2. 删除一个名片")
    print(" 3. 修改一个名片")
    print(" 4. 查询一个名片")
    print(" 5. 显示所有的名片")
    print(" 6. 退出系统")
    print("="*50)

def add_new_card_infor():
    """完成添加一个新的名片"""
    new_name = input("请输入新的名字:")
    new_qq = input("请输入新的QQ:")
    new_weixin = input("请输入新的微信:")
    new_addr = input("请输入新的住址:")

    #定义一个新的字典,用来存储一个新的名片
    new_infor = {}
    new_infor['name'] = new_name
    new_infor['qq'] = new_qq
    new_infor['weixin'] = new_weixin
    new_infor['addr'] = new_addr

    #将一个字典,添加到列表中
    global card_infors
    card_infors.append(new_infor)

    #print(card_infors)# for test

def find_card_infor():
    """用来查询一个名片"""

    global card_infors

    find_name = input("请输入要查找的姓名:")
    find_flag = 0#默认表示没有找到
    for temp in card_infors:
        if find_name == temp["name"]:
            print("%s\t%s\t%s\t%s"%(temp['name'], temp['qq'], temp['weixin'], temp['addr']))
            find_flag=1#表示找到了
            break
    
    #判断是否找到了
    if find_flag == 0:
        print("查无此人....")

def show_all_infor():
    """显示所有的名片信息"""

    global card_infors

    print("姓名\tQQ\t微信\t住址")
    for temp in card_infors:
        print("%s\t%s\t%s\t%s"%(temp['name'], temp['qq'], temp['weixin'], temp['addr']))


def main():
    """完成对整个程序的控制"""
    #1. 打印功能提示
    print_menu()

    while True:

        #2. 获取用户的输入
        num = int(input("请输入操作序号:"))

        #3. 根据用户的数据执行相应的功能
        if num==1:
            add_new_card_infor()
        elif num==2:
            pass
        elif num==3:
            pass
        elif num==4:
            find_card_infor()
        elif num==5:
            show_all_infor()
        elif num==6:
            break
        else:
            print("输入有误,请重新输入")


        print("")

#调用主函数
main()

列表、字典当作全局变量(不用声明global即可使用)

nums = [11,22,33]
infor = {"name":"laowang"}

def test():
    #for num in nums:
    #    print(num)

    nums.append(44)
    infor['age'] = 18

def test2():
    print(nums)
    print(infor)

test()
test2()

#运行会发现新增了age:18

缺省参数(通过定义缺省参数实现免参数传递,若传递,则取传递值)

  • 若要指定传递数据“给谁”,只需注明“谁”=数据。
  • 既可以在函数声明处缺省,又可以在函数调用处缺省
def test(a,d,b=22,c=33):
    print(a)
    print(b)
    print(c)
    print(d)

test(d=11,a=22,c=44)

#运行结果:
soarli@soarli:~/Desktop$ python3 5.py 
22
22
44
11

不定长参数

#一、*代表多余的数据(存在元组中)
def sum_2_nums(a,b,*args):
    print("-"*30)
    print(a)
    print(b)
    print(args)

    result = a+b
    for num in args:
        result+=num
    print("result=%d"%result)

sum_2_nums(11,22,33,44,55,66,77)
sum_2_nums(11,22,33)
sum_2_nums(11,22)
#sum_2_nums(11)#错误,因为 形参中 至少要2个实参

"""
会输出:
------------------------------
11
22
(33, 44, 55, 66, 77)
result=308
------------------------------
11
22
(33,)
result=66
------------------------------
11
22
()
result=33
"""

#二、与缺省参数结合使用
def test(a,b,c=33,*argc):
    print(a)
    print(b)
    print(c)
    print(argc)


test(1,22,33,44,55)
"""
会输出:
soarli@soarli:~/Desktop$ python3 6.py 
1
22
33
(44, 55)

"""


#三、**的引入
#*可以保存多余的不带名字的参数(以元组形式);
#**可以保存多余的带名的参数(以字典形式)

def test(a,b,c,*args,**kargs):
    print(a)
    print(b)
    print(c)
    print(args)
    print(kargs)

test(11,22,33,44,55,66,77,task=99,done=89)

"""
会输出:
soarli@soarli:~/Desktop$ python3 7.py 
11
22
33
(44, 55, 66, 77)
{'task': 99, 'done': 89}

"""

#四、元组/字典的拆包
def test(a,b,c=33,*args,**kwargs):#在定义的时候 *,**用来表示后面的变量有特殊功能
    print(a)
    print(b)
    print(c)
    print(args)
    print(kwargs)


#test(11,22,33,44,55,66,77,task=99,done=89)

A = (44,55,66)
B = {"name":"laowang","age":18}

test(11,22,33,*A,**B)#在实参中*,**表示对元组/字典进行拆包
"""
会输出:
soarli@soarli:~/Desktop$ python3 8.py 
11
22
33
(44, 55, 66)
{'name': 'laowang', 'age': 18}

!!注意:如果在实参中不加*与**,则会输出:

soarli@soarli:~/Desktop$ python3 8.py 
11
22
33
((44, 55, 66), {'name': 'laowang', 'age': 18})
{}

"""

引用(机制与C/C++有明显的不同,对比思考Linux的软硬链接)

soarli@soarli:~/Desktop$ ipython3 
Python 3.6.8 (default, Oct  7 2019, 12:59:55) 
Type "copyright", "credits" or "license" for more information.

IPython 5.5.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: a = 100

In [2]: b = a

In [3]: id(a) #查看a指向的内存地址
Out[3]: 10917664

In [4]: id(b) #查看b指向的内存地址
Out[4]: 10917664

In [5]: #我们发现,a与b指向了同一块内存空间

In [6]: A = [11,22,33]

In [7]: B = A

In [8]: id(A)
Out[8]: 140588910292296

In [9]: id(B)
Out[9]: 140588910292296

In [10]: A.append(44)

In [11]: A
Out[11]: [11, 22, 33, 44]

In [12]: B
Out[12]: [11, 22, 33, 44]

In [13]: #如果此时对A赋新的值,那么B的值不受影响

In [14]: A = [11,22,33]

In [15]: A
Out[15]: [11, 22, 33]

In [16]: B
Out[16]: [11, 22, 33, 44]

可变类型、不可变类型

数字、字符串、元组类型是不可变类型


In [1]: a = "hello"

In [2]: a = "world"  #这样只是修改的a的指向

In [3]: a[0]
Out[3]: 'w'

In [4]: a[0]="W"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-9aa676edea01> in <module>()
----> 1 a[0]="W"

TypeError: 'str' object does not support item assignment

In [5]: #会报错,说明字符串是不可变类型


In [6]: b = (11,22,33)

In [7]: b[0] = "fffff"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-cc56a8aa5121> in <module>()
----> 1 b[0] = "fffff"

TypeError: 'tuple' object does not support item assignment

列表和字典是可变类型


In [8]: a = [11,22,33]

In [9]: a[0] = "fffff"

In [10]: a
Out[10]: ['fffff', 22, 33]

In [11]: a = {"name":"laowang"}

In [12]: a["name"] = "LaoWang"

In [13]: a
Out[13]: {'name': 'LaoWang'}

可变/不可变数据类型的应用:

如字典的key值,只能是不可变类型的数据


In [14]: infor = {"name":"laowang",100:"haha",3.14:"heihei"}

In [15]: infor
Out[15]: {100: 'haha', 3.14: 'heihei', 'name': 'laowang'}

In [16]: infor = {"name":"laowang",100:"haha",3.14:"heihei",(11,22):"ghafd"}
    ...: 

In [17]: infor
Out[17]: {(11, 22): 'ghafd', 100: 'haha', 3.14: 'heihei', 'name': 'laowang'}

In [18]: infor = {"name":"laowang",100:"haha",3.14:"heihei",(11,22):"ghafd",
    ...: [11,12]:"hehe"}
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-18-e3bc5525e613> in <module>()
----> 1 infor = {"name":"laowang",100:"haha",3.14:"heihei",(11,22):"ghafd",[11,12]:"hehe"}

TypeError: unhashable type: 'list'

In [19]: 
#由于哈希算法的限制,可变类型不能当key值(否则改变后无法找到其对应的value)

递归

阶乘的计算

#4! = 4*3*2*1
#5! = 5*4*3*2*1
'''
i = 1
result = 1
while i<=4:
    result = result * i
    i+=1

print(result)
'''


#5! => 5*4!
#4! => 4*3!

'''
def xxx(num):
    num * xxxx(num-1)

def xx(num):
    num * xxx(num-1)

def getNums(num):
    num * xx(num-1)

getNums(4)
'''



def getNums(num):
    if num>1:
        return num * getNums(num-1)
    else:
        return num

result = getNums(4)
print(result)

一定要想清楚什么时候结束递归

def test():
    print("haha")
    test()


test()

#程序会不停输出haha,直到内存超限(或触发系统警告)

列表元素排序方法

数字类型的排序

In [1]: num = [1,423,564,5,87,68,792,3,423]

In [2]: num.sort()

In [3]: num
Out[3]: [1, 3, 5, 68, 87, 423, 423, 564, 792]

In [4]: num2 = [1,423,564,5,87,68,792,3,423]

In [5]: num2.sort(reverse=True)

In [6]: num2
Out[6]: [792, 564, 423, 423, 87, 68, 5, 3, 1]

In [7]: num3 = [1,423,564,5,87,68,792,3,423]

In [8]: num3.reverse()

In [9]: num3
Out[9]: [423, 3, 792, 68, 87, 5, 564, 423, 1]

字典类型的排序:按照指定其键进行,需要使用匿名函数

匿名函数

匿名函数lambda的引入

def test1(a, b):
    return a+b
result1 = test1(11,22)

test2 = lambda a,b:a+b
result2 = test2(11,22)#调用匿名函数



print("result1=%d,result2=%d"%(result1, result2))

"""
运行结果:
result1=33,result2=33
"""

匿名函数lambda的应用(对列表中的字典指定其键进行排序)

infors = [{"name":"laowang","age":10},{"name":"xiaoming","age":20},{"name":"banzhang","age":10}]

infors.sort(key=lambda x:x["name"])

print(infors)

"""
运行结果:
soarli@soarli:~/Desktop$ python3 10.py 
[{'name': 'banzhang', 'age': 10}, {'name': 'laowang', 'age': 10}, {'name': 'xiaoming', 'age': 20}]

若要按照age进行排序,只需将其key改为age
"""

匿名函数作为实参

def test(a,b,func):
    result = func(a,b)
    return result


num = test(11,22,lambda x,y:x+y)
print(num)


"""
运行结果:
33

形参中的a,b,func分别指向11,22,lambda x,y:x+y内存
"""

匿名函数的应用(简易计算器)

我们可以通过自定义一个lambda函数完成11和22的有关计算:

#coding=utf-8

def test(a,b,func):
    result = func(a,b)
    return result
#python2中的方式(不需要eval)
#func_new = input("请输入一个匿名函数:")

#python3中的方式(需要eval)
func_new = input("请输入一个匿名函数:")
func_new = eval(func_new)

num = test(11,22,func_new)
print(num)

"""
运行结果:
>>> 
请输入一个匿名函数:lambda x,y:x+y
33
>>> 

请输入一个匿名函数:lambda a,b:a*b
242

我们可以通过自定义一个lambda函数完成11和22的有关计算
"""

交换两个数的值的三种方法

a = 4
b = 5

#第1种
#c = 0
#c = a
#a = b
#b = c

#第2种(不需要第三个变量)
#a = a+b
#b = a-b
#a = a-b

#第3种(不需要第三个变量)
a,b = b,a

print("a=%d,b=%d"%(a,b))

函数相关知识点补充(什么情况下函数可以修改全局变量值)

对于数字类型


a = 100
  
def test(num):
    num+=num
    print(num)


test(a)

print(a)

"""
运行结果:
soarli@soarli:~/Desktop$ python3 11.py 
200
100
##可见a的值并未被函数修改
"""

结论:若要修改其值,则必须声明global全局变量。

对于列表类型

#a = 100
  
a = [100]

def test(num):
    num+=num
    print(num)


test(a)

print(a)


"""
运行结果:
soarli@soarli:~/Desktop$ python3 11.py 
[100, 100]
[100, 100]
##可见a的值可以被函数修改
"""

对于可变数据类型,函数可以直接修改其值,对于不可变数据类型,函数会将其值复制给一个新定义的局部变量,然后对局部变量进行修改。

在函数里直接修改可变数据类型时的一个坑(num+=num和num=num+num不同,前者可以直接使用,后者相当于定义了一个局部变量num,内存指向全局变量num+num的结果)


#a = 100
  
a = [100]

def test(num):
    #num+=num
    num = num + num # 右边的num指向了a,直接把其值拿来用了,随即计算出[100,100],左边的作用是将num指向[100,100]的内存(此时a仍然指向[100])
    print(num)


test(a)

print(a)
"""
运行结果:
soarli@soarli:~/Desktop$ python3 11.py 
[100, 100]
[100]
"""
最后修改:2020 年 04 月 08 日 06 : 12 PM

发表评论