【Python019--函数与过程】

时间:2024-10-26 20:03:26

一、函数与过程

1、Python只有函数没有过程

>>> def hello():
    print('Hello  fishC!')
>>> temp = hello()
Hello  fishC!
>>> temp
>>> type(temp)
<class 'NoneType'>
>>>

解释:hello赋值给temp,单独temp返回的值是none

2、python可以返回多个值

>>> def back():
    return [1,'尘封',3.14]

>>> back()
[1, '尘封', 3.14]
>>> def back():
    return 1,'尘封',3.14
---利用列表,返回多个值
>>> back()
(1, '尘封', 3.14)
---利用元组返回多个值

二、局部变量和全局变量

局部变量:local Variable  全局变量:Global Variable

函数内的参数以及变量叫局部变量,函数外的变量是全局变量并且函数外无法访问局部变量

1、函数外调用局部变量

def discounts(price,rate):
    fina_price = price * rate #局部变量
    return fina_price

old_price = float(input('请输入原价:'))
rate = float(input('请输入折扣率:'))
new_price = discounts(old_price,rate)
price('打折后价格是:',new_price)
print('函数外打印局部变量final_price的值:',final_price)  #函数外调用局部变量final_price

================= RESTART: /Users/wufq/Desktop/全局变量&局部变量.py =================
请输入原价:100
请输入折扣率:0.8
Traceback (most recent call last):
  File "/Users/wufq/Desktop/全局变量&局部变量.py", line 8, in <module>
    price('打折后价格是:',new_price)
NameError: name 'price' is not defined

为什么报错呢?原因:函数外是无法访问局部变量的

2、函数内调用全局变量

def discounts(price,rate):
    fina_price = price * rate #局部变量
    old_price = 50
    print('修改后的old_price1:',old_price)
    return fina_price

# old_price,rate,new_price都是全局变量,作用域在整个文件,整个模块
old_price = float(input('请输入原价:'))
rate = float(input('请输入折扣率:'))
new_price = discounts(old_price,rate)
print('修改前的old_price2:',old_price)
print('打折后价格是:',new_price)

================= RESTART: /Users/wufq/Desktop/全局变量&局部变量.py =================
请输入原价:100
请输入折扣率:0.8
修改后的old_price1: 50
修改前的old_price2: 100.0
打折后价格是: 80.0
>>>

解释:
1、由打印出的内容可以看出结果还是按照未修改前的变量值进行的
2、函数内修改全局变量old_price,会生成一个新的局部变量,但是名字和全部变量是一样的,强烈要求禁止在函数内定义一个变量名字
和全局变量名字一样的局部变量

三、练习题

1、编写一个函数,判断传入的字符串参数是否为“回文联”(回文联即用回文形式写成的对联,即可顺读,也可倒读。例如:上海自来水来自海上)

思路:

A、确定输入字符串的长度,最后一位,判断中间位置,标志位

B、对比第一位和最后一位,并且最后为对比后递减

def palindrome(string):
    length = len(string) #获取输入string的长度
    last = length -1  #序列是从索引0开始计数,找到最后一个字符的索引,即:下标
    length //=2 #地板除,取string长度的一半,以便后面的for循环前后一半字符串的对比
    flag = 1 #标记位,始终为1即为回文联

for each in range(length): #理解难点,通过for循环进行元素的一一对比,each分别取0,1,2,3
        if string[each]!= string[last]: #前后一个一个的对比
            flag =0  #如果不一样,则置flag = 0 ,即:非回联文
            
        last -=1 #对比完一组以后,进行递减对比第二组

#通过flag是否等于1,来判断是不是回联文
    if flag ==1:
        return 1
    else:
        return 0

String = input('请输入一句话:')
if palindrome(string) ==1:
    print("是回联文")
else:
    print("不是回联文")

2、python实现反转字符串的集中方法

将 string = "abcdef"反转成“fedcba”

string = "abcdef"

#第一种:使用字符串切片
def string_reverse1(string):
    return string[::-1]

print("string_reverse1=",string_reverse1(string))

#第二种:使用reversed()函数
def string_reverse2(string):
    return  ''.join(reversed(string))

#join()函数:将序列中的元素以指定的字符连接生成一个新的字符串

print("string_reverse2=",string_reverse2(string))

#第三种:交换前后字母的位置
def string_reverse3(string):
    t=list(string)
    l = len(t)

#zip()函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的对象
    #如果各个迭代对象的元素个数不一致,则返回的对象长度与最短的可迭代对象相同
    #利用*号操作符,与zip相反,进行解压
    for i,j in zip(range(l-1,0,-1),range(l//2)):
        t[i],t[j]=t[j],t[i]

return ''.join(t)

print("string_reverse3=",string_reverse3(string))

'''for 循环是个难点,一点一点来解析:
1、列出list(range(l-1,0,-1)),打印的结果是:[5, 4, 3, 2, 1]    这里的l=6
2、列出list(range(l//2)),打印的结果是:[0, 1, 2]
3、zip(range(l-1,0,-1),range(l//2)),打印的结果:[(5, 0), (4, 1), (3, 2)]
4、t[i],t[j]=t[j],t[i],是把元组里面的内容交换成[(0, 5), (1, 4), (2, 3)]
5、采用join(t),是把元组内的字符重新连接成一个新的字符串,即进行了交换,变成了:fedcba'''

#第四种:递归的方式,每次输出一个字符
def string_reverse4(string):
    if len(string) <= 1:
        return string
    return string_reverse4(string[1:])+string[0]

print("string_reverse4=",string_reverse4(string))
    
#第五种:使用for循环,从左至右输出
def string_reverse5(string):  
    #return ''.join(string[len(string) - i] for i in range(1, len(string)+1))  
    return ''.join(string[i] for i in range(len(string)-1, -1, -1))
print("string_reverse5=",string_reverse5(string))

3、编写一个函数,分别统计出传入字符串参数的英文字母,空格,数字和其他字符的个数
--Python有4种传值得方式,必选参数fun(param),默认传参fun(param=value),关键字参数fun(**param),可变参数fun(*param)
#1、必选参数 fun(param)
#定义函数时参数个数,顺序已定义好,在调用函数时,参数个数,顺序必须一致,不能多也不能少也不能乱

def test(param1,param2,param3):
    print (param1,param2,param3)

test(1,'hello','尘封')
test('hello',1,'尘封')

'''执行结果:
1 hello 尘封
hello 1 尘封'''
print('*************************')
#2、默认参数 fun(param=value)
#a、定义函数时,已经为参数传入一个默认值,调用函数时不重新传参,则参数已默认值显示
#b、如果必选参数和默认参数同样存在时,则默认参数必然跟在必选参数后面
#c、如果有多个默认参数,调用顺序可以不一致,但是必须要显示表明是哪个默认参数,但是建议按照函数定义的统一顺序进行使用

def fun(param1,param2 = 100,param3= True):
    print(param1,param2,param3)

fun(1)
fun(1,200) #默认参数在必选参数后面
fun(1,param3=False,param2=300)#调用顺序也可以不一致

'''执行结果:
1 100 True
1 200 True
1 300 False'''

print('*************************')
#3、可选参数 fun(*param)
#a、定义函数时,当传入的参数个数不确定,可能是0个,1个, 2个。。。多个时,则可选用可选参数表示,书写格式为参数名称前加一个*号
#b、可选参数在调用时的形式是以一个tuple元组形式存在,即param是一个元组
#c、定义了一个可选参数时,可以把一个列表或者元组作为一个参数进行传递,只需要在传递的时候在前面加上*号
#d、当有必选参数,默认参数,可选参数时,必须按照必选,默认,可选参数进行定义

def fun(param1,param2=100,*param3):

def fun1():
        print(param1,param2)

def fun2():
        print(param1,param2,param3,type(param3))

fun2() if len(param3)!=0 else fun1()

fun(1,2,3,4,5,6)#验证可选函数在调用时是已一个tuple元组形式存在
li =[1,2,3]
ti=(1,2,3)
fun(1,2,*li)#验证传入的可变参数是一个列表
fun(1,2,*ti)#验证 传入的可变参数是一个元组
fun(1,2)

'''执行结果:
1 2 (3, 4, 5, 6) <class 'tuple'>
1 2 (1, 2, 3) <class 'tuple'>
1 2 (1, 2, 3) <class 'tuple'>
1 2'''

print('*************************')
#4、关键字参数fun(**param)
#a、定义函数时,当传入的参数个数不确定时,也可选用关键字参数,与可选参数的区别在于:必须使用默认参数的形式进行传参,例如:param1=1,param2 =2
#b、关键字参数在调用时的形式是以一个dict字典形式存在,即param
#c、定义了一个关键字参数时,可以把一个列表作为一个整体进行传递,只需要在传递的时候在前面加上**
#d、当有必选参数,默认参数,可选参数,关键字参数时,必须按照必选,默认,可选,关键字参数进行定义

def fun(param1,param2=100,*param3,**param4):

def fun1():
        print (param1,param2)

def fun2():
        print (param1,param2,param3,param4,type(param4))

fun2() if len(param3)!=0 and len(param4)!=0 else fun1()

fun(1,2,3,4,a=5,b=6,c=7)#验证可选函数在调用时是已一个tuple元组形式存在,关键字函数在调用时已一个字典的形式存在
dict= {"a":1,"b":2,"c":3}
fun(1,2,3,4,**dict) #传入的可变参数是一个字典dict
fun(1,2)

#需求:编写一个函数,分别统计出传入的字符串参数的英文字母,空格,数字和其他字符的个数

def count(*param):#可选参数
    length = len(param) #获取传入参数的长度

for i in range(length):

#给英文字母,空格,数字和其他一个初始值
        letter = 0
        space = 0
        digit = 0
        others = 0

#在参数内进行循环判断
        for each in param[i]:
            if each.isalpha():
                letter +=1
            elif each.isspace():
                space +=1
            elif each.isdigit():
                digit +=1
            else:
                others +=1

print('第 %d 个字符串共有:英文字母 %d个,空格 %d个,数字 %d个,其他字符 %d个' %(i+1,letter,space,digit,others))

count('i love www.yizhibo.com/666','i love you','you love me')

'''执行结果:
第 1 个字符串共有:英文字母 18个,空格 2个,数字 3个,其他字符 3个
第 2 个字符串共有:英文字母 8个,空格 2个,数字 0个,其他字符 0个
第 3 个字符串共有:英文字母 9个,空格 2个,数字 0个,其他字符 0个
'''