python3-常用结构体介绍

函数
数学中的函数相当于一种映射关系,参数通过一系列数学变换来计算生成一个结果

编程中的函数和数学中的函数是相似的,编程中的函数指的是一段可以被重复使用的代码

函数的格式
1.函数定义(分配任务)
def关键字,注意之前提到的硬性规则和软性规则

def 函数名(形参列表):
        函数体(这一部分要带有一级缩进,带有缩进的代码,才是函数内部的语句)
        return 返回值(函数的返回值,函数执行到retun,意味着执行完了,return后面的值,就是函数的返回值,return语句并不是必须的,可以有,也可以没有)
形参列表中可以有多个形参,多个形参(形式参数)间使用逗号分隔

2.函数调用(开始执行任务,完成任务)
第一种:
函数名(实参列表,实际参数,简称实参,此处写的实参的个数要和形参的个数匹配)
第二种:
返回值 = 函数名(实参列表)
Python中要求,函数定义写在前面,函数调用写在后面--先定义,后调用
推荐函数名这么写calc_Sum,都可以
PEP8是Python里面一套非常流行的程序规范,也是写代码中的一些软性要求
在C++/Java里,不光要求形参和实参的个数匹配,类型也要匹配
但是在Python里,只是要求个数,对类型没有要求(因为Python里存在动态类型)
所以Python里传什么都行,可以顺利运行,顺利打印出来
Python里也可以写return
def add(x, y):
        return x + y
只要保证函数体里的操作能正常运行,就可以
# 在实际开发中,一般都倾向于第二种写法,有一个通用的编程原则:一个函数只做一件事!
# 这样一旦后续需要改变和用户的交互方式,第二种写法就更有优势。当前是通过控制台和用户交互的
# 让逻辑和交互/界面能够分离,进一步的好处有:解耦合(避免藕断丝连的影响)。
# 在一个稍微复杂一些的程序中,经常会涉及到很多个模块,模块之间可能要进行交互,有些交互耦合性比较强,有些交互耦合性比较弱
# 我们期望尽量通过良好的涉及来让耦合降低。
# 耦合:一方产生一些变动,对另一方产生的影响


# 这种情况不算是有多个return语句的
# def test():
#     return 1
#     return 2
#
# # 一般多个return语句是搭配 分支语句/循环语句的
# def is_odd(num):
#     """
#     用来判断是不是奇数,如果是奇数,则返回True,如果不是返回False
#     :param num: 要判定的数
#     :return: 返回True/False来表示是不是奇数
#     """
#     if num % 2 == 0:
#         return False
#     else:
#         return True
#
# print(is_odd(10))
# print(is_odd(19))

# 写一个函数,返回平面上的一个点
# 横坐标,纵坐标
# def get_point():
#     x = 10
#     y = 20
#     return x, y
# # 就可以一次返回多个值了
# # 多元赋值
# a, b = get_point()
#
# #虽然现在返回了多个值,但是我只想用其中一部分,不关注其他的,可以使用下划线来占位:
# _, d = get_point()# 可以写个下划线占位
函数的返回值
一个函数中是可以有多个返回语句的

当执行到return时就不再往下执行了,而是回到了调用位置(函数结束)

一个函数可以返回多个值,比起C++/Java好很多,因为这两种语言调用一个函数一次只能返回一个值。如果C++想返回多个值,需要通过输出型参数(指针/引用)。如果Java想要返回多个值,需要把多个值给包装成一个对象,返回这个对象。而Python直接用逗号分割就可以了

但是有时候,虽然返回了多个值,但是我们只想用其中的一部分,不关注其他的,可以使用下划线来占位

# 写一个函数,返回平面上的一个点
# 横坐标,纵坐标
def get_point():
    x = 10
    y = 20
    return x, y
# 就可以一次返回多个值了
# 多元赋值
a, b = get_point()
 
#虽然现在返回了多个值,但是我只想用其中一部分,不关注其他的,可以使用下划线来占位:
_, d = get_point()# 可以写个下划线占位。这里把y直接赋给了d
当没有return时,执行到末尾也就结束了 

变量的作用域


 链式调用
把一个函数的返回值,作为另一个函数的参数

 嵌套调用
一个函数的函数体内部,还可以调用其他函数。就叫做嵌套调用

一个函数里面可以嵌套调用任意多个函数

def a ():
    print ( " 函数 a" )
def b ():
    print ( " 函数 b" )
    a ()
def c ():
    print ( " 函数 c" )
    b ()
def d ():
    print ( " 函数 d" )
    c ()
d ()
def a ():
    print ( " 函数 a" )
def b ():
    a ()
    print ( " 函数 b" )
def c ():
    b ()
    print ( " 函数 c" )
def d ():
    c ()
    print ( " 函数 d" )
d ()
函数递归
函数自己调用自己

递归的两个要素:

1.递归结束条件

2.递归的递推公式

类似于数学归纳法:

1.初始条件

2.递归公式

递归的缺点:

1.执行过程非常复杂,难以理解

2.递归代码容易出现“栈溢出”的情况

3.递归代码一般都是可以转换成等价的循环代码的。并且循环的版本通常运行速度要比递归的版本有优势(函数调用也是有开销的)既慢又占空间

递归的优点:

代码非常简洁,尤其是处理一些“问题本身就是通过递归的方式定义的”

数据结构中的二叉树本身就是通过递归的方式定义的额,有时候处理二叉树就需要用到递归解决问题

参数默认值
Python中的函数,可以给形参指定默认值

带有默认值的参数,可以再调用的时候不传参

关键字参数
按照先后顺序来传参,这种传参风格称为“位置参数”,这是各个编程语言中最普遍的方式。

关键字传参,按照形参的名字来进行传参

 位置参数和关键字参数还能混着用,只不过混着用的时候要求位置参数在前,关键字参数在后

关键字参数,一般也就是搭配摩恩参数来使用的。一个函数,可以提供很多的参数,来实现对这个函数的内部功能做出一些调整设定,为了降低调用者的使用成本,就可以把大部分参数设定出默认值(导出默认值)

当调用者需要调整其中的一部分参数的时候,就可以搭配关键字参数来进行操作

函数小结:
函数的定义
函数的调用
函数的参数传递过程
函数的执行流程(进去好近,出来不好出)
列表和元组
变量一定程度上代表着内存 空间,用来表示/存储数据

如果表示的数据少,直接定义几个变量就行了

那么需要表示的数据很多时,该怎么办呢?

列表可以管理很多元素

在Python中,列表和元组(类似于其他编程语言中的“数组”)可以用一个变量来表示很多个数据

列表和元组,大部分功能都是差不多的,但是有一个功能有非常明显的区别:

列表是可变的,创建好了之后,随时能改

元组是不可变的,创建好了之后,改不了,要想改,就只能丢弃旧的,搞个新的

列表可变,元组不可变

创建列表:
1.直接使用字面值来创建

在Python中[ ]就表示一个空的列表

a = [ ]

2.使用list()来创建

b = list()

推荐使用[]来创建列表,因为[]能方便我们在创建列表时指定初始值,元素之间用,分割

a = [1, 2, 3, 4, 5]

C++/Java里要求一个数组里只能存相同类型的变量,而Python里可以在一个列表里放不同类型的变量

列表的下标访问:

我们可以通过下标访问的方式(用到下标访问运算符[])来获取到列表中的元素

a = [ ]

把[]放到一个列表变量的后面,同时[]里写上一个整数,此时它就是下表访问运算符,[]中间写的这个证书,就是称为“下标”或者“索引”

下标是从0开始计数的

当我们下标超出有效范围时,就会出现异常

可以使用len来测列表长度

a = [1, 2, 3, 4]

print(len(a))

len可以传字符串,列表,元组,字典,自定义的类...一个函数能支持这么多类型,背后的原理:动态类型

Python中的下标其实还可以写成负数,例如写成-1,其实等价于len(a)-1

# 下标为-1时,其实等价于len(这个列表)-1
a = [1, 2, 3, 4]
print(len(a))
print(len(a) - 1)
print(a[len(a) - 1])
print(a[-1])
# -1这个下标就是倒数第一个元素
结果:

4

3

4

4

也可以认为-1这个下标就是倒数第一个元素

切片操作:
一次取出一组连续的元素

# 关于切片操作的基本使用
a = [1, 2, 3, 4]
print(a[1:3])
切片操作中,[]里面有两个数字,表示了一段区间。

1表示开始区间的下标,3表示结束区间的下标。取下标1到3的元素,但是这里包含1不包含3,前闭后开

切片操作是可以省略前后的两个边界的

切片操作是一个比较高效的操作,进行切片的时候,只是取出了原有列表中的一个部分,并不涉及到“数据的拷贝”。假设有一个很大的列表进行切片,切片的范围也很大,即使如此,切片操作仍然非常高效(没有去拷贝什么的)

切片操作还可以指定“步长”,

# 切片操作中指定步长的操作
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(a[::1])# 这里的1就是步长,指每次走的长度
print(a[::2])
print(a[1:-1:2])
print(a[::-2])# 步长的数值还可以是负数,当步长为负数时,意思是从后往前取
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 3, 5, 7, 9]
[2, 4, 6, 8]
[10, 8, 6, 4, 2]

# 当切片中的范围超出有效下标之后,不会出现异常!而是尽可能的把符合要求的元素给取到
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(a[1:100])
[2, 3, 4, 5, 6, 7, 8, 9, 10]

当然,单纯访问时越界是会报错的

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# print(a[1:100])
print(a[100])
Traceback (most recent call last):
  File "C:\Users\14534\Desktop\Python\code12.py", line 85, in <module>
    print(a[100])
IndexError: list index out of range

遍历
把一个列表里的每个元素都一次取出来,并进行某种操作,不重不漏

遍历往往要搭配循环

在列表中插入元素
# 使用append往列表末尾新增元素
a = [1, 2, 3, 4, 5]
# 此处的append是搭配列表对象a来一起使用的,而不是作为一个独立的函数
# 这种要搭配对象(变量)来使用的函数,也叫作“方法”
# type,print,input,len,自定义函数...都是独立的函数
a.append(5)
a.append("hello")
print(a)

b = [5, 6, 7, 8]
b.append("world")
print(b)
# 使用insert往列表的任意位置来新增元素
a = [1, 2, 3, 4]
a.insert(1, "hello")# 第一个参数是要往哪个位置去插,第二个参数是要插入的元素是什么
a.insert(100, "hello")# 并不是报错或扩展列表,而是插到末尾
print(a)
在列表中查找元素
# 使用in来判断某个元素是否在列表中存在
a = [1, 2, 3, 4, 5]
print(1 in a)# 存在返回True,不存在返回False
print(17 in a)
print(1 not in a)
print(10 not in a)

# 使用index来判断当前元素在列表中的位置,得到一个下标
a = [1, 2, 3, 4, 5]
print(a.index(2))# 看2存不存在,如果存在,就返回2的下标,如果不存在,会抛出异常
删除列表元素
# 删除元素pop,remove
a = [1, 2, 3, 4, 5]
a.pop()# 不传参的话删除掉的是末尾元素
print(a)

# 使用pop还能删除任意位置的元素,pop的参数可以传一个下标过去
a = [1, 2, 3, 4]
a.pop(1)# 删除该下标元素
print(a)

# 使用remove来按照值来删除
a = ["aaa", "bbb", "ccc", "ddd"]
a.remove("ccc")
print(a)
列表的拼接
# 使用“+”针对两个列表进行拼接
# a = [1, 2, 3, 4, 5]
# b = [6, 7, 8, 9, 10]
# c = a + b# 谁在前,谁的内容就在前,谁在后,谁的内容就在后
# print(c)

# 使用extend来进行拼接
# 这个拼接是把后一个列表的内容拼接到前一个列表里面,这样做会修改原来的列表
# a = [1, 2, 3, 4, 5]
# b = [6, 7, 8, 9, 10]
# a.extend(b)
# c = a.extend(b)
# print(a)
# print(b)
# print(c)# 打印出的结果是None
# # 关于None,这是一个特殊的变量值,表示啥都没有
# # extend其实是没有返回值的,如果拿变量接收没有返回值的返回值,就什么都没有
# # None非常类似于C里面的NULL,或Java里的null,或C++里的nullptr

# 使用+=来进行拼接
a = [1, 2, 3, 4]
b = [5, 6, 7, 8]
a += b
print(a)
print(b)
# 那么它和extend有什么区别呢?
# a = a + b相当于把a原先的值被a+b覆盖了,相比较之下比较低效
# extend更高效

 元组
创建元组

# 创建元组
# a = ()# 表示一个空的元组
# print(type(a))
# b = tuple()# 空的元组
# print(type(b))
# # 创建元祖的时候,可以指定初始值
# a = (1, 2, 3, 4)
# print(a)

# 元组中的元素也可以是任意类型的
# a = (1, 2, True, "hello", [])
# print(a)

# 通过下标来访问元组中的元素,下表也是从0开始的,到len-1结束
# a = (1, 2, 3, 4)
# print(a[1])
# print(a[-1])
# print(a[100])# 抛出异常,下标越界

# 通过切片来获取元组中的一部分
# a = (1, 2, 3, 4)
# print(a[1:3])
#
#
# # 也可以使用for循环等方式来遍历元素
# a = (1, 2, 3, 4)
# for elem in a:
#     print(elem)
#
#
# # 也可以使用in判断元素是否存在,使用index来查找元素的下标
# a = (1, 2, 3, 4)
# print(3 in a)
# print(a.index(3))
#
# # 可以使用+来拼接两个元组
# a = (1, 2, 3, 4)
# b = (5, 6, 7, 8)
# print(a + b)
# 注意,以上操作都是没有改变元组的,元组只要创建好,就不能改变了。虽然a + b是把元组拼接,但是a,b的本体是没有改变的

# 元组只是支持读操作(只读),不支持修改
a = (1, 2, 3, 4)
# 所以以下这些都不行
# a[0] = 100
# a.append(5)
# a.pop(0)
# a.extend()
# 这些涉及修改元组的都是不可行的,元组能读但是不能修改。这是它和列表的很大的区别

# 当进行多元赋值的时候,其实本质上是按照元组的方式来进行工作的
def get_point():
    x = 10
    y = 20
    return x, y

x, y = get_point()# 构造新元组
print(type(get_point()))# 这里的get_point()就是元组

# 那么为什么有了列表还要有元组呢?
# 既然列表已经可读可修改了,为什么还要有元组这个只可读的呢?
# 因为协同开发的时候,有时候需要程序员1实现一些功能,提供给程序员2来使用,1写好一些函数,让2去调用。
# 2在使用函数,在传参时,可能纠结一个问题,把参数传过去了,1的函数里面是否会把2的参数的内容给改了呢?
# 当我们使用元组作为参数时,就可以避免这样的纠结
# 元组不能修改(也称为不可变对象)。不可变对象是可以哈希的!(一会后面再介绍)不可变对象可以哈希,意思是:它可以作为字典的那个键。
# 不可变对象天然就是线程安全的
————————————————
版权声明:本文为CSDN博主「列宁格勒的街头」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_60320290/article/details/126690204

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值