Python编程-从0到1基础知识串讲(变量,分支循环,可变参数问题,传递字典,列表,模块创建,模块引用)

Python编程-从基础类型到函数使用的语法规则梳理与使用案例

动态变量类型特性

python作为一门弱类型语言,对于变量的处理是自动的,对于同一变量名修改时不会限制修改类型,它只有字符串,整型,浮点型,布尔型作为基本类型

a = 10  # 则a是int型变量
a = 22.2  # 此时a则为float型变量
a = [1,2,3,4,5]  # 此时a则是一个列表 字典等也是同理
a = 2 ** 3  #  python使用双 * 求取数的次方

print函数使用案例

输出内容拼接时默认是字符串

print(str(1)+" is a value!")  # 不使用str转换将会报错
print(1,"is a value!")   # 使用,分割不会报错,并且会自动在不同类型间添加空格

输出的两个选项sependsep默认的值为空格,end默认值为换行,需要注意的是输出时仅仅对所在的语句进行有效控制

print(1,2)  
print(3)  # 输出1 2后换行为3
print(1,2,sep='-',end='-') # 输出 1-2-3
print(3)

输出数据时可以使用对应处理变量的方法

print("aaa".upper())  # 输出AAA

name = "AAa"
print(name.title())  # 输出Aaa

将变量插入print

value = 123
print(f"the value is {value}")

布尔型与逻辑判断

True
False
'''注意首字母大写'''

需要注意的是,在进行逻辑运算时,or或者and并不一定会返回一个布尔型数据:

print(True or False)
print(True and False)
print(233 and "abc")
print(233 or "abc")
print(False or "abc")

在Python中,and 运算符返回其第一个假值(False,0,空字符串,空列表等),或者最后一个值。在这种情况下,233 是真值,因此 and 返回其后面的字符串 "abc"。所以最终结果是 "abc" 被打印出来。

在Python中,or 运算符返回其第一个真值(True,非零数字,非空字符串,非空列表等),或者最后一个值。因此,对于 print(233 or "abc")233 是一个真值,所以 or 返回 233,最终结果是 233 被打印出来。

字符串及其不可变性

python中为处理字符串提供了许多方法(字符串使用''"",需要注意如果字符串中出现不同引号注意保证输出正确)

表达式描述
a.strip() + b移除a字符串两端的空格后与b拼接
a.lstrip() + b移除a字符串左端的空格后与b拼接
a.rstrip() + b移除a字符串右端的空格后与b拼接
a.upper() + ba字符串转换为大写后与b拼接
a.lower() + ba字符串转换为小写后与b拼接
a.title() + ba字符串转换为首字母大写后与b拼接
a * 3输出a字符串重复三次作为一个新字符串

在Python中,字符串是不可变的,这意味着一旦创建了字符串对象,就无法更改其内容。每次对字符串进行操作(例如拼接、切片等)时,实际上都会创建一个新的字符串对象,而不是在原始字符串上进行修改。同时对于同样的字符串变量,其引用的都是同一个字符串

我们可以使用 id() 函数来验证字符串的不可变性。id() 函数返回对象的唯一标识符,可以用来检查两个变量是否引用同一个对象。如果两个变量引用的是同一个对象,则它们具有相同的 id

a = "hello"
b = "hello"

print(id(a))  # 打印变量a的id
print(id(b))  # 打印变量b的id

# 修改字符串
a += " world"

print(id(a))  # 再次打印变量a的id,会发现id已经改变了

input函数使用案例

注意 input默认输入也是字符串,在运算时需要进行转换,并且python无double

a = int(input())
print(a/2)

这里需要注意一个问题,我们将python输入转化为int时,如果输入float类型将会报错,python不支持将高级数据向低级转化,我们加入输入提示并换行:

a = int(input("输入提示\n"))
print(a/2)

结合or的语法还可以在输入为空时返回一个默认字符串:

a = input("输入提示\n") or "这是默认值"
print(a)

条件分支语句

仅控制单个条件后的行为,以马老师比武为例

age = 12
if age < 69 :
    print("小伙子不讲武德")

此代码运行后年龄小于69时,将会输出小伙子不讲武德,表示符合条件,但是对大于14者却没有限制,此时则引入else

age = 70
if age < 69 :
    print("小伙子不讲武德")
else:
    print("原来是有备而来")

此时,凡是年龄大于69者都将输出原来是有备而来,因为并不符合if条件,如果需要引入不同层级则需要elif并且加入逻辑运算符,下面继续以马老师为例

age = 25
if age < 20:
    print("你两个手来掰我一个手指头")
elif age > 20 and age < 69:
    print("来骗来偷袭69岁老同志")
elif age > 69 and age < 72:
    print("传统武林讲究以和为贵")
else :
    print("我当时流眼泪了说婷婷")

这里将会输出来骗来偷袭69岁老同志,但是这样用逻辑运算符会使得代码比较冗杂,容易把马老师的cpu干烧,于是python支持以下格式,使得格式更加简单

age = 25
if age < 20:
    print("你两个手来掰我一个手指头")
elif 20 < age < 69:
    print("来骗来偷袭69岁老同志")
elif 69 < age < 72:
    print("传统武林讲究以和为贵")
else:
    print("我当时流眼泪了说婷婷")

但是有些时候我们只想检测单个条件下的成立,而不关注不符合条件会怎样,则可以舍弃else

weight = 1000
hand = 4
if weight == 1000:
    if hand == 4:
        print("传统功夫是讲化劲的 四两拨千金")

正确输出传统功夫是讲化劲的 四两拨千金,婷婷看了都说好

weight = 2500
hand = 4
if weight == 1000:
    if hand == 4:
        print("传统功夫是讲化劲的 四两拨千金")
else :
    print("按传统功夫的点到为止他已经输了")

使用else语句时在一般情况下,与最近的if结合,而这里由于特殊缩进而输出按传统功夫的点到为止他已经输了

并且注意到分支语句的嵌套

同时分支语句的条件是是否成立,即可以用布尔型代替

weight = True
age = True
if age :
    if weight:
        print("我劝这位年轻人好自为之 好好反思")

可以看到,当年龄与体重符合事实时,马老师说我劝这位年轻人好自为之 好好反思

循环处理语句

基于while的循环

两年半前的今天,马老师因为没做好筛选被20多岁小伙子偷袭,今年马老师更加谨慎,决定筛选一下选手

  1. 选手只能是大于69岁,小于72岁的老同志
list = [69,69,70,71,72]
i = 0
while i < len(list):
    if 69<=list[i]<=72:
        print("武林要以和为贵")
        i += 1

可以看到马老师欢迎所有老同志,并且表示武林要以和为贵

  1. 但是有年轻人看不惯马老师这种行为,于是潜入了选手中,发生了以下事故
list = [69, 69, 70, 71, 72]
i = 0
list.append(20)
list.append(20)  # 年轻人和好朋友潜入了选手列表
while i < len(list):
    if list[i] >= 69:
        print("松果弹抖闪电鞭")
        i += 1
    else:
        print("来骗来偷袭69岁老同志")  # 马老师遗憾离场
        i += 1
  1. 马老师不服气,于是使用混元功法,让时光倒流,加入了赛前检查(检查列表中是否有这种元素,并且进行操作)
list = [69, 69, 70, 71, 72]
list.append(20)  # 年轻人潜入了选手队列
list.append(20)  # 年轻人的好朋友潜入
while 20 in list:  # 表示如果20岁的小伙子在list中,则循环不终止
    list.remove(20)
print(list,"刚才有两个小伙子问发生什么事了")  # 年轻人遗憾离场
  1. 马老师吸取了教训,想出了两个解决方案
list = [69, 69, 70, 20, 71, 21, 72]
i = 0
while i < len(list):
    if list[i] >= 69:
        print("武林要以和为贵")
        i+=1
    else:
        print("小伙子你不讲武德 我不打了")
        break   # 马老师用break终止了比赛进行

但是这个方法好吗,这不好,后面还有老同志没有进行比赛

list = [69, 69, 70, 20, 71, 21, 72]
i = 0
while i < len(list):
    if list[i] < 69:
        print("年轻人好自为之 不要玩这样的小聪明")
        i+=1
        continue  # 用continue跳过了后面的操作 将年轻人移出了赛场
    print("武林要以和为贵")
    i+=1  

基于for的循环

又过了两年半,马老师的婷婷出差去了(while代码中的定义的i不能用了),于是马老师决定自己虚拟一个婷婷,并且开始比赛(即在结构内部的局部变量)

  1. 进行选手初选
list = [69, 69, 70, 20, 71, 21, 72]
for i in range(0,len(list)):
    if list[i]<69:
        print("年轻人你好自为之")   # 年轻人离场
list = [69, 69, 70, 20, 71, 21, 72]
for i in list:
    if i < 69:
        print("年轻人你好自为之")  # 年轻人离场

可以注意到两种不同的循环方式,但是他们都是将in后面的值逐个赋值给i这个临时变量

  1. 没有婷婷的马老师想快速结束战斗,于是让选手按次序间隔相同距离,选取挑战(调整for循环的步长)
list = [69, 69, 70, 20, 21, 71, 72]
for i in range(0, len(list), 2):
    if list[i] < 69:
        print("年轻人你好自为之")  # 很不幸 狡诈的年轻人被抽到了
    else:
        print("武林要以和为贵@",list[i])
  1. 没有婷婷的马老师,毫无比赛斗志
list = [69, 69, 70, 20, 21, 71, 72]
for i in range(0, len(list), 2):
    if list[i] < 69:
        print("小伙子你不讲武德 我不打了")
        break;  # 遇到小伙子,即终止了比赛
    else:
        print("谢谢朋友们")
  1. 婷婷在赛程中途偷偷回来看马老师比赛,婷婷心里有马老师,而马老师也注意到了婷婷,他心里有婷婷,马老师重燃斗志
list = [69, 69, 70, 20, 21, 71, 72]
for i in range(0, len(list), 2):
    if list[i] < 69:
        print("小伙子你不讲武德 按传统功夫的规矩你已经输了 而且你没有婷婷")
        continue
    print(" 谢谢朋友们 谢谢婷婷 ")

下面介绍python中的几大重要数据类型

列表

创建

代码描述
list = []创建一个空列表,没有元素可供访问。
list = [1,"2",3,"4","5"]创建并初始化一个包含整数和字符串的列表。
list = list(range(1,10))创建并初始化一个包含1到9升序排列整数的列表。

访问

代码描述
list = [1,"a",3,"4","b"]创建并初始化一个包含整数和字符串的列表。
print(list[1])访问列表中的第二个元素(下标为1),输出字符串 "a"
print(list[1].upper())输出列表中的第二个元素转换为大写的结果,即 "A"
print(list[-5])输出列表中倒数第五个元素,即整数 1
print(list)输出整个列表 [1, "a", 3, "4", "b"]

操作

操作特定元素

list_1 = [3,2,1,4,5,2]
list_2 = ['a','b','d','c','e','f','g']
代码描述
value = len(list_1)使用 len() 方法统计 list_1 列表中元素的个数,并将结果赋值给 value 变量。
list_1.append(6)使用 append() 方法向 list_1 列表末尾添加元素 6
list_2.pop(1)使用 pop() 方法弹出 list_2 列表中索引为 1 的元素(即第二个元素),并返回该元素。
list_1.remove(2)使用 remove() 方法删除 list_1 列表中的第一个值为 2 的元素。
list_1.insert(2, 7)使用 insert() 方法在 list_1 列表的索引为 2 的位置(即第三个位置)插入值为 7 的元素。

操作整个列表

代码描述
list.reverse()将列表 list 中的元素倒置,但不进行排序。
new = sorted(list)对列表 list 进行排序,生成一个新的已排序列表 new,但不改变原列表的顺序。
list.sort()对列表 list 进行升序排序,直接修改原列表。
list.sort(reverse=True)对列表 list 进行降序排序,直接修改原列表。
list.index(元素)查找列表 list 中指定元素的索引,如果不存在则报错。
print(元素 in list)检查指定元素是否在列表 list 中,返回布尔值。
  • 注意sortsorted都可以使用reverse=True选项,并且是支持字符排序的

列表切片

list_1 = [1,2,3,4,5]
代码描述
list_2 = list_1[2:4]使用切片操作,将 list_1 中索引为 2 到索引为 3 的元素复制给 list_2
list_2 = list_1[2:]使用切片操作,将 list_1 中索引为 2 到结尾的元素复制给 list_2
list_2 = list_1[:]使用切片操作,将 list_1 中的所有元素复制给 list_2
list_2 = list_1[:2]使用切片操作,将 list_1 中索引为 0 到索引为 1 的元素复制给 list_2
list_2 = list_1[:-2]切片操作中也可以使用负数索引,表示从末尾开始计数。
  • 误区
list_2 = [1, 2, 3, 4, 5]
list_1 = list_2
print(id(list_1))
print(id(list_2))  

list_3 = list_2[:]  # 将2复制给1的正确操作
print(id(list_3))

原因在于Python中的列表,元组,字典,集合均为对象,对于单个名称保留的实质上是它们的引用,赋值符实质上传递的仍然是个引用

遍历

for i in range(0,len(list)):
    print(list[i])

列表脚本操作符

列表对 + 和 * 的操作符与字符串相似。+ 号用于组合列表,* 号用于重复列表:

Python 表达式结果描述
len([1, 2, 3])``3长度
[1, 2, 3] + [4, 5, 6][1, 2, 3, 4, 5, 6]组合
['Hi!'] * 4['Hi!', 'Hi!', 'Hi!', 'Hi!']重复
3 in [1, 2, 3]True元素是否存在于列表中
for x in [1, 2, 3]: print(x, end=" ")1 2 3迭代

列表函数&方法

这类方法需要注意,它们的实现实质上是实现了一些模拟容器协议,与普通的私有方法不同

函数描述
len(list)列表元素个数
max(list)返回列表元素最大值
min(list)返回列表元素最小值
list(seq)将其他对象转换为列表

列表对象的内置方法:

方法描述
list.append(obj)在列表末尾添加新的对象。
list.count(obj)统计某个元素在列表中出现的次数。
list.extend(seq)在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)。
list.index(obj)从列表中找出某个值第一个匹配项的索引位置。
list.insert(index, obj)将对象插入列表。
list.pop([index=-1])移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。
list.remove(obj)移除列表中某个值的第一个匹配项。
list.reverse()反向列表中元素。
list.sort(key=None, reverse=False)对原列表进行排序。
list.clear()清空列表。
list.copy()复制列表。

元组

创建

tuple = (1,2,3)  # 通常使用元组会初始化 因为元组中的元素无法被单独修改
tuple = tuple(range(1,10)) # 另一种处理方式

访问

由于元组不可更改的特性 操作比较局限 但是大体上与列表类似

tuple = (1,2,3)
tuple = (1,2,3,4)  # 修改元组指向 元素个数可以不一致
代码描述
print(tuple[1])访问元组 tuple 中的第二个元素(索引为 1)。
print(tuple[-1])访问元组 tuple 中的倒数第一个元素。
print(len(tuple))输出元组 tuple 的长度。
print(5 in tuple)检查元素 5 是否存在于元组 tuple 中,返回布尔值。
print(tuple.index(4))查找元素 4 在元组 tuple 中的索引,如果不存在则报错。
temp = tuple[1:3]使用切片操作,将元组 tuple 中索引为 1 到索引为 2 的元素复制给 temp

元组类型的不可变性

元组的不可变指的是元组所指向的内存中的内容不可变,因为元组类型实质上没有提供可改变自身数据的方法。通过以下代码观察结果还可以知道三个元组类型变量实质上的引用的内存是一样的

tuple_1 = (1, 2, 3, 4, 5)
tuple_2 = tuple_1
print(id(tuple_2))
print(id(tuple_1))  

tuple_3 = tuple_1[:] 
print(id(tuple_3))

遍历

for i in range(0,len(tuple)):
    print(tuple[i])

元组运算符

与字符串一样,元组之间可以使用 +、**+=**和 ***** 号进行运算。这就意味着他们可以组合和复制,运算后会生成一个新的元组类型引用。

Python 表达式描述
result = tuple1 + tuple2将元组 tuple1tuple2 连接起来,创建一个新的元组 result,包含了所有元组 tuple1tuple2 的元素。
tuple1 += tuple2将元组 tuple1tuple2 连接起来,更新元组 tuple1,使其包含所有元组 tuple1tuple2 的元素。
result = ('Hi!',) * 4创建一个新的元组 result,包含了 'Hi!' 这个元素重复 4 次的结果。
is_included = 3 in (1, 2, 3)检查元素 3 是否存在于元组 (1, 2, 3) 中,返回布尔值 is_included

元组内置方法

方法描述
len(tuple)计算元组中元素的个数。
max(tuple)返回元组中最大的元素。
min(tuple)返回元组中最小的元素。
tuple(iterable)将可迭代序列转换为元组。

字典

  • python精髓,使用key:value类型,通过键访问

创建

dir = {}  # 创建空字典
dir = {'1':'a','2':'b','3':'c'} # 创建并且初始化 格式为 键:值

注意:字典是将传入的值的哈希值作为标准比较,某些不同的类型数据,他们的哈希值可能是一样的,所以建议使用字符作为键

访问

dir = {'1':'a','2':'b','3':'c'}
dir['1'] = 'A'  # 访问并且修改键 1 的值
dir['4'] = 'd'  # 字典中没有4这个键 即添加 4:'d' 这项内容
del dir['4']  # 删除字典中 键4 以及对应的 值'd'

遍历

for key, value in dir.items():  # 遍历字典
    print(key,value,sep=':')  # 注意在未加方法时 遍历的顺序是随机的 但是3.6及之后是按插入顺序排列
# 注意在未加方法时 遍历的顺序是随机的 但是3.6及之后是按插入顺序排列 同上
for i in dir.keys():  # 遍历键
    print(i)
for i in dir.values():  # 遍历值
    print(i)
for i in sorted(dir.keys()):  # 按顺序遍历键,其他同理 但是不推荐 速度影响较大
    print(i)
for i in dir.keys():
    print(dir[i])  # 以键遍历值

注意 python 只关心键与值的对应关系 而不在意其顺序

字典内置函数&方法

函数及描述实例
len(dict)计算字典 dict 中元素的个数,即键的总数。
str(dict)输出字典 dict 的字符串表示形式,可以打印出来。
type(variable)返回输入变量 variable 的类型,如果变量是字典则返回字典类型。

Python字典包含了以下内置方法:

函数描述
dict.clear()删除字典内所有元素。
dict.copy()返回一个字典的浅复制。
dict.get(key, default=None)返回字典 dict 中键 key 对应的值,如果键不存在则返回 default 值。
dict.fromkeys(seq, val=None)创建一个新字典,以序列 seq 中的元素作为字典的键,val 为所有键对应的初始值。
dict.get(key, default=None)返回指定键 key 的值,如果键不在字典中,则返回设置的默认值 default
key in dict如果键在字典 dict 中则返回 True,否则返回 False
dict.items()以列表返回一个包含所有字典键值对的视图对象。
dict.keys()返回一个包含所有字典键的视图对象。
dict.setdefault(key, default=None)类似于 get() 方法,但如果键不存在于字典中,将会添加键并将值设为 default
dict.update(dict2)将字典 dict2 中的键值对更新到字典 dict 中。
dict.values()返回一个包含所有字典值的视图对象。
dict.pop(key[,default])删除并返回字典中键为 key 的键值对的值,如果 key 不存在则返回 default
dict.popitem()删除并返回字典中的最后一个键值对。

集合

集合(set)是一个无序的不重复元素序列。集合中的元素不会重复,并且可以进行交集、并集、差集等常见的集合操作。可以使用大括号 { } 创建集合,元素之间用逗号 , 分隔, 或者也可以使用 set() 函数创建集合

  • 创建集合:
set_one = {1, 2, 3, 4, 5}		# 直接使用{ } 创建集合
list = [1, 2, 3, 4, 5]		# 从列表创建集合
set_two = set(list)			
  • 创建空集合
set_three = set()
  • 集合运算

集合运算内容来自菜鸟教程:https://www.runoob.com/python3/python3-set.html

>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  
{'a', 'r', 'b', 'c', 'd'}
>>> a - b                              # 集合a中包含而集合b中不包含的元素
{'r', 'd', 'b'}
>>> a | b                              # 集合a或b中包含的所有元素
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b                              # 集合a和b中都包含了的元素
{'a', 'c'}
>>> a ^ b                              # 不同时包含于a和b的元素
{'r', 'd', 'b', 'm', 'z', 'l'}

集合内置方法完整列表

方法描述
dict.add()为集合添加元素。
dict.clear()移除集合中的所有元素。
dict.copy()拷贝一个集合。
dict.difference()返回多个集合的差集。
dict.difference_update()移除集合中的元素,该元素在指定的集合也存在。
dict.discard()删除集合中指定的元素,如果元素不存在,不会发生错误。
dict.intersection()返回集合的交集。
dict.intersection_update()返回集合的交集。
dict.isdisjoint()判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。
dict.issubset()判断指定集合是否为该方法参数集合的子集。
dict.issuperset()判断该方法的参数集合是否为指定集合的子集。
dict.pop()随机移除元素。
dict.remove()移除指定元素,如果元素不存在,则会发生错误。
dict.symmetric_difference()返回两个集合中不重复的元素集合。
dict.symmetric_difference_update()移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。
dict.union()返回两个集合的并集。
dict.update()给集合添加元素,且参数可以是列表,元组,字典等。
len(dict)计算集合元素个数。

推导式运算示例

  • 推导式的基本结构
[表达式 for 变量 in 列表] 
  • 带条件的推导式
[表达式 for 变量 in 列表 if 条件表达式] 

推导式在使用时是将列表中的元素进行迭代,将其内容输出到开头的表达式中,条件表达式则用于筛选迭代的内容,根据返回的内容类型有以下4类,将依次给出示例

列表推导式

  • 推导式实验准备
import random
'''使用此脚本生成一个随机序列用于实验'''

if __name__ == "__main__":
    list =[]
    for i in range(0, 15):
        list.append(random.randint(1, 200))
    print(list)				# 我这里是:[7, 20, 170, 166, 84, 196, 55, 182, 147, 31, 55, 155, 69, 86, 164]

接下来我们以筛选偶数为例写一个列表推导式:

list = [7, 20, 170, 166, 84, 196, 55, 182, 147, 31, 55, 155, 69, 86, 164]

even_number = [ value for value in list if (value % 2 ==0) ] 
print(even_number, "\n", type(even_number))
'''
运行结果:
    [20, 170, 166, 84, 196, 182, 86, 164] 
    <class 'list'>
'''

字典推导式

字典推导式略有区别,我们需要为值,键都定义一个表达式,如下示例:

list = ['Python', 'v3.11.6', 'Hello', 'World']

dict = { list.index(value)+1 : value for value in list }
print(dict, "\n", type(dict))
'''
运行结果:
    {1: 'Python', 2: 'v3.11.6', 3: 'Hello', 4: 'World'} 
    <class 'dict'>
'''

集合推导式

与列表类似,不过集合中具有去重功能,并且其也不关心顺序:

list = ['Python', 'v3.11.6', 'Hello', 'World', 'Python', 'World']

set_one = { set_element for set_element in list }
print(set_one, "\n", type(set_one))
'''
运行结果:
    {'Hello', 'Python', 'v3.11.6', 'World'} 
    <class 'set'>
'''

元组推导式

元组推导式又叫做生成器推导式,下面通过示例我们来展示其不同之处:

tuple_one = ( x for x in range(1,13) )

print(tuple(tuple_one), "\n", type(tuple_one))

'''
运行结果:
    (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12) 
    <class 'generator'>
'''

我们如果想输出元组推导式,必须将其转化为元组对象,从type可知其推导式结果为一个生成器

建立无参函数

按照国际惯例,先输出hello world以表敬意:

def hello_world():
    print("hello_world")
 
hello_world()

我们可以看到,def与后面的所有缩进构成了一个代码块,我们称之为一个函数,函数名为hello_world,其后面的括号表示传入的参数,当然此时是没有参数的,同时,如果我们需要调用多次函数,我们则需要书写多次

建立一个参数的函数

我们以求1-n的和为例,要求输入一个数,求出1到它的和,我们来用函数实现

def function(cnt):
    num = sum(range(1,cnt+1))
    print(num)

num = int(input())
function(num)

如上,我们简单定义了一个函数function(),并且向其中传入了一个参数num,并且在该函数中求出了1-n的值,(注意在函数内的参数与主函数内参数重名是没有关系的,不会影响到主函数内变量的值)下面我们来介绍形参实参

形参:我们在函数中的括号处定义的参数即形参,它只在函数内生效,如cnt

实参:我们在调用函数时传入函数内的参数,如num

建立多个参数的函数

我们以求n-m的和为例,要求输入两个数

第一种:位置实参

def function(x, y):
    num = sum(range(x, y+1))
    print(num)

n = int(input())
m = int(input())
function(n, m)

此时求解的是n-m的和,此时n对应x,m对应y,我们称为位置对应,如果n与m对应位置出错,代码将会出错

第二种:关键字实参

def function(x, y):
    num = sum(range(x, y+1))
    print(num)

n = int(input())
m = int(input())
function(y=m, x=n)

此时我们为y与x指定了对应的实参,指定后实参顺序将不会影响函数的运行,我们将得到正确的运算结果,并且关键字实参必须放在参数表的最后(或者全部为关键字实参),以免出现部分位置实参位置错误

带默认参数的函数

在调用函数时,我们有时候需要为函数指定默认值,则可以为它指定一个值,我们称之为默认参数,但是默认参数必须放在参数列表的最后面,以防止出错

def function(x, y=5):
    num = sum(range(x, y+1))
    print(num)

function(2,4)
function(1)
function(x=1)

如上所示,我们指定默认y=5,在导入实参时,指定第二个为4,则默认求解2-4的和,在只写第一个参数为1时,我们求解的是1-5的和,并且在此情况下的关键字实参仍然生效,如代码中的function(x=1)

同时我们需要注意的是,函数的参数可以是基本类型变量,常量,也可以是列表,字典等,并且在书写默认参数函数时会出现一个问题:

def append_element(element, default_list=[]):
    default_list.extend(element)
    return default_list

if __name__ == "__main__":
    print(append_element([1, 2]))
    print(append_element([3, 4]))

在 Python 中,默认参数(如 default_list=[])在函数定义时会被计算和存储一次,并在每次调用该函数时都重用相同的对象。这意味着,默认参数在函数多次调用中会保留之前调用时的状态。default_list 的默认值是一个空列表 []。当第一次调用 append_element([1, 2]) 时,这个空列表被扩展为 [1, 2] 并返回。然而,在下一次调用 append_element([3, 4]) 时,这个默认的列表 default_list 仍然是 [1, 2],因为它是在函数定义时创建的,并且在之后的每次调用中都保持不变。为了避免这种行为,可以将默认参数设置为 None,并在函数内部检查并创建一个新的空列表,如下所示:

def append_element(element, default_list=None):
    if default_list is None:
        default_list = []
    default_list.extend(element)
    return default_list

带返回值的函数

在许多时候,我们不需要在函数中打印某值,而是在主函数中输出,在函数中进行预处理,我们仍然以求1-n的和为例,返回一个值给主函数,同时返回值可以是基本类型变量,常量,也可以是列表,字典

def function(cnt):
    num = sum(range(1,cnt+1))
    return(num)

num = int(input())
print(function(num))

如上,我们在函数中计算,在主函数中使用函数返回值输出

向函数中传递字符串

先给出示例代码,先给出一个姓名zhang san,输出hello zhang san

def function(name):
    print("hello" + " " + name)

function("zhang san")

可以看出与上述代码并无本质区别,但是我们假设有位置项,而有些人不愿意透露自己的位置呢,此时我们可以定义一个默认参数为空字符串的值,如下示例:

def function(name, address=''):
    print("hello" + " " + name+" "+address)

function("zahng san")
function("li si","beijing")

但是我们需要注意的是,前面所叙述的数字变量不能如此操作

向函数中传递字符串的某一部分

在处理数据时,我们有时候需要向函数中传递字符串的某一片段,我们可以利用切片进行操作:

def function(str):
    print("11"+str+"11")

str = "12223 44"
function(str[5:6])

上述代码将输出11 11

向函数中传递列表

def function(list):
    list.pop()
    print(list)

list = [1, 2, 3, 4, 5]
function(list)
print(list)

我们向函数中传递列表,然后弹出最后一个值,最后再次在主函数中打印列表,运行此代码我们会发现主函数中的列表也发生了改变,这就是传递列表与上述不同的一个地方,但是我们有时候需要避免这一点,我们可以复制一份列表:

def function(list):
    list.pop()
    print(list)

list = [1, 2, 3, 4, 5]
function(list[:])
print(list)

这样的话,我们就可以在不修改主函数中原始列表的情况下,于函数中操作列表,同时如上述的字符串一样,我们也可以向函数中传递切片,此处类似,不做过度赘述

向函数中传递可变位置参数

我们可以利用如下代码进行操作,将多个数量未知参数传给函数:

def function(a,*str):
    print(a)
    for i in str:
        print(i)

function(1,2,3,4,5)

如上,利用*str这个元组接收多个参数,并且在函数中逐个打印

向函数中传递元组

由于元组的特性是不可修改元素,所以与列表有些许区别:

def function(temp):
    temp=(1,2)
    print(temp)
   
tuple = (1,2,3)
function(tuple)
print(tuple)

输出结果时发现,主函数中的元组未发生改变,为(1, 2, 3)

向函数中传递字典

如果我们要向函数中传递字典或者关键字实参,我们可以如下操作:

传递可变关键字参数

def function(temp_1, temp_2, **str):
    dir = {}
    dir['a'] = temp_1
    dir['b'] = temp_2
    for key, value in str.items():
        dir[key] = value
    print(dir)

function(1, 2, c=3, d=4, e=5)

这里的可变参数实际上是字典

向函数传递字典

def function(str):
    del str['1']
    print(str)

dir_test = {'1':'a','2':'b','3':'c'}
function(dir_test)
print(dir_test)

传递字典时和列表一样,函数中修改,主函数中的也会改变,如果不想改变,可以将其设置为可变参数:

def function(**str):
    del str['1']
    print(str)

dir_test = {'1':'a','2':'b','3':'c'}
function(**dir_test)
print(dir_test)

返回各种参数

在函数中处理好的基本变量和列表,字典等都可以直接用return直接返回,这里仅用字典示例不做过多叙述:

def function():
   dir_test = {1:'a',2:'b',3:'c'}
   return dir_test

dir = function()
print(dir)

函数的优点是可以将代码封装到模块中进行使用,给函数指定描述性名称,使主程序更加简洁易读

创建与使用模块

建立hello_world.py文件,并且只保留函数部分

def hello_world():
    print("hello_world")
    
def HiPython():
    print("hi python")

如上所示,我们可以在同一函数模块中建立多个函数

在主函数中使用该模块

import hello_world

hello_world.hello_world()

我们通过import引入我们编写的hello_world.py模块(此时我们导入的是整个模块中的函数),再通过.取文件中的hello_world函数进行运行,这种方法通常用在项目中需要使用同一个模块中的多个函数的时侯

基本格式:import [模块名]

导入特定的函数

有时候我们只会使用模块中的某一个函数,为了增强代码可读性,我们有以下操作:

from hello_world import hello_world

hello_world()

此时注意到,我们直接使用的是导入过来的函数名称,这便是引入特定函数的操作

基本格式:from [模块名] import [函数名]

导入所有函数

有时候我们需要导入模块中的所有函数,但是由不想使用.运算符,我们可以使用以下操作:

from hello_world import *

hello_world()
HiPython()

这样就可以避免使用.运算符,造成书写冗杂,可读性降低等问题,如果我们使用的时别人编写好的模块,我们进行这种操作时需要慎重,慎防项目中的其他函数被覆盖

使用别名

我们发现,hello_world函数名很长,而且有时候我们的代码里也可能与之重名,所以我们需要为它指定一个简短的别名:

from hello_world import hello_world as hi

hi()

但是需要注意的是,我们在后面的代码中必须使用该别名(在未指定新的别名时)

函数的递归调用

和其他语言一样,python是支持递归的,我们以输入一个数n,求1-n的和为例

def t(n):
    if n>=1:
        return t(n-1)+n
    else:
        return 0  # 为避免程序出错,加上结束时的返回值
    
n = int(input())
print(t(n))

但是,由于python特性,递归的深度有较大限制,不宜过深递归

函数嵌套调用

python的函数也是可以嵌套的,而且不用根据定义顺序来调用

def test_1(t):
    if test_2(t):
        print("yes")
    else:
        print("no")


def test_2(t):
    if t < 100:
        return True
    else:
        return False


a = 101
test_1(a)

控制位置与关键字参数传递

/之前的参数只能通过位置传递,不能通过关键字传递。这意味着在调用函数时,必须按照函数定义中参数的顺序提供参数值。

def func(a, b, /, c, d):
    print(a, b, c, d)

# 通过位置传递参数
func(1, 2, 3, 4) 

# 通过关键字传递参数会报错
func(a=1, b=2, c=3, d=4) 

报错如下:

1 2 3 4
Traceback (most recent call last):
  File "d:\CodeFolder\tempCodeRunnerFile.py", line 8, in <module>
    func(a=1, b=2, c=3, d=4) 
    ^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: func() got some positional-only arguments passed as keyword arguments: 'a, b'

*之后的参数只能通过关键字传递,不能通过位置传递。这意味着在调用函数时,必须使用参数名来指定参数值,而不能简单地按照参数在函数定义中的顺序提供参数值。

def func(a, b, *, c, d):
    print(a, b, c, d)

# 通过关键字传递参数
func(1, 2, c=3, d=4) 

# 通过位置传递参数会报错
func(1, 2, 3, 4) 

报错如下:

1 2 3 4
Traceback (most recent call last):
  File "d:\CodeFolder\arg_test.py", line 8, in <module>
    func(1, 2, 3, 4) 
    ^^^^^^^^^^^^^^^^
TypeError: func() takes 2 positional arguments but 4 were given
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值