当前位置: 首页 > news >正文

【python】-基础语法3

在这里插入图片描述
💖作者:小树苗渴望变成参天大树🎈
🎉作者宣言:认真写好每一篇博客💤
🎊作者gitee:gitee✨
💞作者专栏:C语言,数据结构初阶,Linux,C++ 动态规划算法🎄
如 果 你 喜 欢 作 者 的 文 章 ,就 给 作 者 点 点 关 注 吧!

文章目录

  • 前言
  • 一、函数是什么?
  • 二、变量的作用域
  • 三、参数的默认值和关键字参数
  • 四、列表和元祖
    • 4.1两者的区别
    • 4.2 创建列表
    • 4.3访问下标
    • 4.4切片操作
    • 4.5遍历列表元素
    • 4.6新增元素
    • 4.7查找元素
    • 4.8删除元素
    • 4.9连接列表
    • 4.10关于元组
  • 五、字典
    • 5.1字典是什么
    • 5.2创建字典
    • 5.3查找key
    • 5.4新增/修改元素
    • 5.5删除元素
    • 5.6遍历字典元素
    • 5.7合法的key类型
  • 六、结语


前言

通过上一篇的基础语法我们学习了条件判断以及循环相关知识,发现除了缩进这一块在编写代码的时候需要多注意,其他方面比其他语言使用起来简单一些,今天博主给大家讲解一下新的知识,函数和列表,在我们所以语言中都有的,他能极大的给我们开发带来方便。


一、函数是什么?

编程中的函数和数学中的函数有一定的相似之处,是一段可以被重复使用的代码片段。
一段相同逻辑的代码可能因为参数不一样要被编写许多次,而函数就是降低这样所带来的冗余度。来看代码示例:

# 定义函数
def calcSum(beg, end):sum = 0for i in range(beg, end + 1):sum += iprint(sum)
# 调用函数
calcSum(1, 100)
calcSum(300, 400)
calcSum(1, 1000)

不然我们需要写三段定义函数的代码,这样显得代码非常冗余。

(1)基本语法格式
创建函数/定义函数(define)

def 函数名(形参列表):函数体return 返回值

带有缩进的代码才是函数内部的语句,同样也是没有{}这样的语法。

(2)调用函数

函数名(实参列表)           // 不考虑返回值
返回值 = 函数名(实参列表)   // 考虑返回值

函数定义并不会执行函数体内容, 必须要调用才会执行. 调用几次就会执行几次

注意: python中的函数定义不需要关注参数和返回值类型,因为我们有动态类型的特性。调用的方式和其他语言也是一样的,参数个数和顺序要匹配,其次函数必须先定义在调用,这是因为我们的程序是顺序执行的。先调用会出现改函数找不到的情况。

(3)函数的返回值
函数的参数可以视为是函数的 “输入”, 则函数的返回值, 就可以视为是函数的 “输出” .

此处的 “输入”, “输出” 是更广义的输入输出, 不是单纯指通过控制台输入输出.
我们可以把函数想象成一个 “工厂”. 工厂需要买入原材料, 进行加工, 并生产出产品.
函数的参数就是原材料, 函数的返回值就是生产出的产品

下列代码

def calcSum(beg, end):sum = 0for i in range(beg, end + 1):sum += iprint(sum)calc(1, 100)

可以转换成

def calcSum(beg,end):sum=0for i in range(beg,end+1):sum+=ireturn sumresult=calcSum(1,5)
print(result)

这两个代码的区别就在于, 前者直接在函数内部进行了打印, 后者则使用 return 语句把结果返回给函数调用者, 再由调用者负责打印.

我们一般倾向于第二种写法. 为了解耦合

  1. 实际开发中我们的一个通常的编程原则, 是 “逻辑和用户交互分离”. 而第一种写法的函数中, 既包含了计算逻辑, 又包含了和用户交互(打印到控制台上). 这种写法是不太好的, 如果后续我们需要的是把计算结果保存到文件中, 或者通过网络发送, 或者展示到图形化界面里, 那么第一种写法的函数, 就难以胜任了.
  2. 而第二种写法则专注于做计算逻辑, 不负责和用户交互. 那么就很容易把这个逻辑搭配不同的用户
    交互代码, 来实现不同的效果.

在其他语言中我们要想实现一个函数返回多个函数值是比较困难的,可能需要指针或者数组,对象的方式返回出来,但我们的python天然就只支持一次返回多个值原因是我们在基础语法1中就介绍过多元赋值,这样就可以支持我们函数可以返回多个值了

代码示例:使用,进行分割就可以

def getpoint():x=10y=20return x,ya,b=getpoint()
print(a,b)

如果只想关注其中的部分返回值, 可以使用 _ 来忽略不想要的返回值

def getPoint():x = 10y = 20return x, y
_, b = getPoint()

二、变量的作用域

我们在学习其他的语言的时候,应该都听说过全局变量和局部变量,怎么区分这两种变量呢,就是通过作用域的不同来区分这两个变量,我们的pylon中也是有变量的作用域这个概念的。我们来看一下下面的示例代码:

def getPoint():x = 10y = 20return x, y
x, y = getPoint()

在这个代码中, 函数内部存在 x, y, 函数外部也有 x, y.
但是这两组 x, y 不是相同的变量, 而只是恰好有一样的名字

我们来验证一下:变量只能在所在的函数内部生效
在函数 getPoint() 内部定义的 x, y 只是在函数内部生效. 一旦出了函数的范围, 这两个变量就不再生效了.
在这里插入图片描述

确实和我们看到的效果是一样的,并且在不同的作用域中,允许存在同名的变量

全局变量在整个程序运行周期都是有效的,而局部变量只在当前所在函数内部有效。我们来验证一下。

内外变量互相访问:
(1)通过函数内部访问局部变量,前提是函数内部没有和全局变量重名的变量:
在这里插入图片描述

如果函数内部尝试访问的变量在局部不存在, 就会尝试去全局作用域中查找

(2)在函数外部访问函数内部的局部变量需要加一个global关键字
在这里插入图片描述

如果此处没有 global , 则函数内部的 x = 10 就会被视为是创建一个局部变量 x, 这样就和全局变量 x 不相关了。

其次,if / while / for 等语句块不会影响到变量作用域,换而言之, 在 if / while / for 中定义的变量, 在语句外面也可以正常使用,这里面就不给大家演示案例了,知道就行了。

三、参数的默认值和关键字参数

我们在C++里面里面也学习过参数的默认值,不就在函数有,对象传惨的时候也有,这个可以给我们编程带来一定的方便,所以python将这个好的特性给保留下来了。

(1)参数的默认值
带有默认值的参数,可以在调用的时候不传惨,我们来看下面的例子:

此处 debug=False 即为参数默认值. 当我们不指定第三个参数的时候, 默认 debug 的取值即为 False. 我们看打印函数的写法print(add(1,2,True))把一个函数的返回值,作用另一个函数的参数,这种操作称为是链式调用

注意:带有默认值的参数需要放到没有默认值的参数后面
在这里插入图片描述

这样没有默认值的参数才能按照顺序与传进来的参数进行匹配。这一点和C++里面的要求是一样的。

(2)关键字参数
在调用函数的时候, 需要给函数指定实参. 一般默认情况下是按照形参的顺序, 来依次传递实参的.
但是我们也可以通过 关键字参数, 来调整这里的传参顺序, 显式指定当前实参传递给哪个形参。
在这里插入图片描述

关键字参数可以非常明显告诉程序员实参传递给哪个形参了。具体的作用会在文件部分进行讲解。

四、列表和元祖

4.1两者的区别

两者在其他语言里面的叫法为数组,只不过在python里面叫做列表和元祖。作用就是代码中需要表示的数据特别多,甚至也不知道要表示多少个数据的时候,就需要使用他们。

列表是一种让程序猿在代码中批量表示/保存数据的方式

就像我们去超市买辣条, 如果就只是买一两根辣条, 那咱们直接拿着辣条就走了. 但是如果一次买个十根八根的, 这个时候用手拿就不好拿, 超市老板就会给我们个袋子. 这个袋子, 就相当于 列表

元组和列表相比, 是非常相似的, 只是列表中放哪些元素可以修改调整, 元组中放的元素是创建元组的时候就设定好的, 不能修改调整.

列表就是买散装辣条, 装好了袋子之后, 随时可以把袋子打开, 再往里多加辣条或者拿出去一些辣条.
元组就是买包装辣条, 厂家生产好了辣条之后, 一包就是固定的这么多, 不能变动了.
在这里插入图片描述

我们先介绍列表,在介绍元组,只要列表里面的操作不修改元素的值在元祖中都是适用的。

4.2 创建列表

创建列表有两种方式:
第一种:[]表示一个空列表

alist=[]

第二种: 使用内置类型list()

alist=list()

在这里插入图片描述


内置类型只能进行空的列表的初始化,如果想往里面设置初始值,可以直接写在[]当中,所以我们后面使用列表的时候几乎都使用第一种方式了,我们来看看怎么设置列表初始值

a=[1,2,3,4]
print(a)

在这里插入图片描述

重点: 在我们的数组当中,数组里面的元素必须是相同类型,但是我们列表里面不需要相同类型,这是差距之一。
在这里插入图片描述

因为有了动态类型的特性,我们之前认为一个变量只能存储一个值,但是现在表面看上去我们的变量却存储了多个值,但实际上这个变量是一个列表类型。形式和普通变量一样而已。

4.3访问下标

数组就是通过下标来访问数组元素的,当然列表也是通过这样的方式进行去访问列表元素的。

可以通过下标访问操作符 [ ] 来获取到列表中的任意元素。

我们把 [ ] 中填写的数字, 称为 下标 或者 索引 .

alist = [1, 2, 3, 4]
print(alist[2])

在这里插入图片描述
注意: 下标是从 0 开始计数的, 因此下标为 2 , 则对应着 3 这个元素.这个从C语言开始就一直是这样的。所以现在每个语言都是采用下标从0开始的

通过下标修改列表里面元素的值和数组是一样的,如果下标超过列表范围,会抛出异常,这里就不做详细的代码演示了


访问列表的长度
因为下标是从 0 开始的, 因此下标的有效范围是 [0, 列表长度 - 1]. 使用 len 函数可以获取到列表的元素个数

alist = [1, 2, 3, 4]
print(len(alist))

在这里插入图片描述

len也是一个内建函数,可以穿很多参数,求字符串,列表,元组,字典等长度,得益于动态类型的特性。

不一样的点:下标可以取负数,这是在其他语言是实现不了的。表示:“倒数第几个数”
在这里插入图片描述

在这里插入图片描述
我们发现第二三打印的效果是一样的,只是python为了简化把len()去掉了alist[-1] 相当于 alist[len(alist) - 1]

4.4切片操作

通过下标操作是一次取出里面的一个元素.
通过切片, 则是一次取出一组连续的元素, 相当于得到一个子列表

使用 [ : ] 的方式进行切片操作

alist = [1, 2, 3, 4]
print(alist[1:3])

在这里插入图片描述

alist[1:3] 中的 1:3 表示的是 [1, 3) 这样的由下标构成的前闭后开区间.
也就是从下标为 1 的元素开始(2), 到下标为 3 的元素结束(4), 但是不包含下标为 3 的元素.所以最终结果只有 2, 3

  1. 切片操作中可以省略前后边界
alist = [1, 2, 3, 4]
print(alist[1:])        # 省略后边界, 表示获取到列表末尾
print(alist[:-1])       # 省略前边界, 表示从列表开头获取
print(alist[:])         # 省略两个边界, 表示获取到整个列表

在这里插入图片描述

  1. 切片操作还可以指定 “步长” , 也就是 "每访问一个元素后, 下标自增几步
alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(alist[::1])
print(alist[::2])
print(alist[::3])
print(alist[::5])

在这里插入图片描述

  1. 切片操作指定的步长还可以是负数, 此时是从后往前进行取元素. 表示 “每访问一个元素之后, 下标自减几步”
alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(alist[::-1])
print(alist[::-2])
print(alist[::-3])
print(alist[::-5])

在这里插入图片描述

  1. 如果切片中填写的数字越界了, 不会有负面效果. 只会尽可能的把满足条件的元素截取到.
alist = [1, 2, 3, 4]
print(alist[100:200])

在这里插入图片描述

通过上面四种切片操作我们发现操作的方式有很多,对于程序员来说就有了很大的操作空间。并且切片是一个非常高效的事情,不会因为要切的数据很多,效率就变低了,因为不涉及到数据的拷贝,只是取出来。

4.5遍历列表元素

“遍历” 指的是把元素一个一个的取出来, 再分别进行处理。

第一种方式使用for循环

在这里插入图片描述

列表也1类似于可迭代对象range,将列表a里面的元素依次赋值给i,把i打印出来,也不一定是打印,其他操作也是可以,但是不会是列表a本身的数据发生变化

在这里插入图片描述

也可以通过列表的下标进行访问,此时要是对a[i]进行操作可能会影响列表本身的值

第二种方式使用while循环,也类似于for循环的第二种方式
在这里插入图片描述

4.6新增元素

有两个方法,一个尾插一个任意位置插入

  1. 使用 append 方法, 向列表末尾插入一个元素(尾插)
alist = [1, 2, 3, 4]
alist.append('hello')
print(alist)

在这里插入图片描述

  1. 使用 insert 方法, 向任意位置插入一个元素
    insert 第一个参数表示要插入元素的下标.
alist = [1, 2, 3, 4]
alist.insert(1, 'hello')
print(alist)

在这里插入图片描述

PS: 什么是 “方法” (method)
方法其实就是函数. 只不过函数是独立存在的, 而方法往往要依附于某个 “对象(可视为变量)”.
像上述代码 alist.append , append 就是依附于 alist, 相当于是 "针对 alist 这个列表, 进行尾插操作

4.7查找元素

  1. 使用 in 操作符, 判定元素是否在列表中存在. 返回值是布尔类型

在这里插入图片描述

  1. 使用 index 方法, 查找元素在列表中的下标. 返回值是一个整数. 如果元素不存在, 则会抛出异常
    在这里插入图片描述

在我们c++/java中我们通常使用-1来表示元素不存在,而在【python中所有整数都可以表示下标,所以只能报异常错误,所以防止我们都程序终止,我们通常使用in和index搭配着来使用。

4.8删除元素

  1. 使用 pop 方法删除元素
    在这里插入图片描述

pop不传惨参数默认是删除最末尾元素,而传参数就是列表下标表示删除第几个元素。

  1. 使用remove方法,按照值进行删除元素 ,值必须在列表中可以找到。
    在这里插入图片描述

4.9连接列表

我们的列表既然可以允许不同类型的值在一起,那我们也可以把不同的列表拼接在一起。
使用 + 能够把两个列表拼接在一起.
此处的 + 结果会生成一个新的列表clist. 而不会影响到旧列表的内容

alist = [1, 2, 3, 4]
blist = [5, 6, 7]
//clist=alist+blist
print(alist + blist)

在这里插入图片描述

使用 extend 方法, 相当于把一个列表拼接到另一个列表的后面

a.extend(b) , 是把 b 中的内容拼接到 a 的末尾. 不会修改 b, 但是会修改 a.

alist = [1, 2, 3, 4]
blist = [5, 6, 7]
alist.extend(blist)
print(alist)
print(blist)

在这里插入图片描述

alist.extend(blist)等价于alist+=blist

但是alist.extend(blist)更加高效,因为不涉及创建临时变量,拷贝到原空间,释放原来的元素,而是直接进行拼接的。其次extend()方法无返回值,所以当用变量接收时会返回一个None

4.10关于元组

元组的功能和列表相比, 基本是一致的.
元组使用 ( ) 来表示.
创建元组

atuple=()
btuple=tuple()
print(type(atuple))
print(type(btuple))

在这里插入图片描述
元组不能修改里面的元素, 列表则可以修改里面的元素
因此, 像读操作,比如访问下标, 切片, 遍历, in, index, + 等, 元组也是一样支持的.
但是, 像写操作, 比如修改元素, 新增元素, 删除元素, extend 等, 元组则不能支持.
另外, 元组在 Python 中很多时候是默认的集合类型. 例如, 当一个函数返回多个值的时候.

在这里插入图片描述
此处的 result 的类型, 其实是元组.

问题来了, 既然已经有了列表, 为啥还需要有元组

元组相比于列表来说, 优势有两方面:

  1. 你有一个列表, 现在需要调用一个函数进行一些处理. 但是你有不是特别确认这个函数是否会把你的列表数据弄乱. 那么这时候传一个元组就安全很多.
  2. 我们马上要讲的字典, 是一个键值对结构. 要求字典的键必须是 “可hash对象” (字典本质上也是一个hash表). 而一个可hash对象的前提就是不可变. 因此元组可以作为字典的键, 但是列表不行

1.列表和元组都是日常开发最常用到的类型. 最核心的操作就是根据 [ ] 来按下标操作.
2.在需要表示一个 “序列” 的场景下, 就可以考虑使用列表和元组.
3.如果元素不需要改变, 则优先考虑元组.
4.如果元素需要改变, 则优先考虑列表.

五、字典

5.1字典是什么

我们在学习c++的时候讲到过map这种数据结构,所以字典是一种存储键值对的结构。
啥是键值对? 这是计算机/生活中一个非常广泛使用的概念.
把 键(key) 和 值(value) 进行一个一对一的映射, 然后就可以根据键, 快速找到值

举个栗子, 学校的每个同学, 都会有一个唯一的学号.
知道了学号, 就能确定这个同学.
此处 “学号” 就是 “键”, 这个 “同学” 就是 "值

5.2创建字典

我们在列表和元组的时候已经把()和[]这两种括号类型用掉了,而创建一个空的字典. 使用 { } 表示字典

a={}
b=dict()
print(type(a))
print(type(b))

在这里插入图片描述

· 也可以在创建的同时指定初始值
· 键值对之间使用 , 分割, 键和值之间使用 : 分割. (冒号后面推荐加一个空格).
· 使用 print 来打印字典内容
· 为了代码更规范美观, 在创建字典的时候往往会把多个键值对, 分成多行来书写.
· 最后一个键值对, 后面可以写 , 也可以不写

student={'id':1,'name':'hangman'
}
print(student)

在这里插入图片描述

5.3查找key

  1. 使用 in 可以判定 key 是否在 字典 中存在. 返回布尔值
student={'id':1,'name':'hangman'
}
print('id' in student)
print('score' in student)

在这里插入图片描述

  1. 使用 [ ] 通过类似于取下标的方式, 获取到元素的值. 只不过此处的 “下标” 是 key. (可能是整数, 也可能是字符串等其他类型).
student={'id':1,'name':'hangman'
}
print(student['id'])
print(student['score'])

在这里插入图片描述

如果 key 在字典中不存在, 则会抛出异常. 所以防止程序异常终止,我们的[]通常搭配in一起使用

5.4新增/修改元素

使用 [ ] 可以根据 key 来新增/修改 value.
· 如果 key 不存在, 对取下标操作赋值, 即为新增键值对
在这里插入图片描述

我们发现student这个字典里面没有‘score’这个key,所以我们就新增了这个关键字,但我们发现出现了黄色波浪形警告,原因是pycharm检测到,我们创建了一个字典,又新增了一个key,可以在创建的时候就一起写进去进行初始化,不需要分两步。

· 如果 key 已经存在, 对取下标操作赋值, 即为修改键值对的值
在这里插入图片描述

5.5删除元素

· 使用 pop 方法根据 key 删除对应的键值对.

student={'id':1,'name':'hangman','score':90
}
student.pop('score')
print(student)

在这里插入图片描述

5.6遍历字典元素

· 直接使用 for 循环能够获取到字典中的所有的 key, 进一步的就可以取出每个值了.

student={'id':1,'name':'hangman','score':90
}
for key in student:print(key,student[key])

在这里插入图片描述

这里面可以为student是一个可迭代对象,依次取出里面的key

接下来有三种字典自带的方法:
1.取出所有的key.
2.取出所有的value
3.取出所有的key和value

  1. 使用 keys 方法可以获取到字典中的所有的 key
student = {'id': 1,'name': 'zhangsan','score': 80
}
print(student.keys())

在这里插入图片描述

我们看到取出来的类型‘dict_keys’,大家千万不要把他当成列表去使用了,并且‘dict_keys’是一个可迭代对象,用在上面的for循环里面也是可以的。但是

  1. 使用 values 方法可以获取到字典中的所有 value
student = {'id': 1,'name': 'zhangsan','score': 80
}
print(student.values())
print(type(student.values()))

在这里插入图片描述

  1. 使用 items 方法可以获取到字典中所有的键值对
student = {'id': 1,'name': 'zhangsan','score': 80
}
print(student.items())
print(type(student.items()))

5.7合法的key类型

不是所有的类型都可以作为字典的 key。
字典本质上是一个 哈希表, 哈希表的 key 要求是 “可哈希的”, 也就是可以计算出一个哈希值。

可以使用 hash 函数计算某个对象的哈希值.
但凡能够计算出哈希值的类型, 都可以作为字典的 key.

在这里插入图片描述

  1. 列表无法计算哈希值
print(hash([1, 2, 3]))

在这里插入图片描述

  1. 字典也无法计算哈希值
print(hash({ 'id': 1 }))

在这里插入图片描述

通过上面的论证我们发现不可改变的内容一般可作为哈希值,能改变的做不了哈希值。
字典也是一个常用的结构. 字典的所有操作都是围绕 key 来展开的.
需要表示 “键值对映射” 这种场景时就可以考虑使用字典

六、结语

今天我们学习了许多关于python当中的语法,里面的内容很多,但是需要理解的却不多,只要之前学习过其他语言,这些知识相比较其他语言的知识还是非常好理解的。所以大家下去一定要多练习练习,熟能生巧。基础语法只是学习python的一小部分,我们python为什么开发效率高,得益于他的标准库和第三方库,所以下一篇博主就给大家介绍这两个库,用别人现成的东西进行开发,效率会高很多。我们下期再见。

相关文章:

  • flutter开发音乐APP(简单的音乐播放demo)
  • Android Compose 无网络状态处理全指南:从基础到高级实践
  • 家庭服务器IPV6搭建无限邮箱系统指南
  • 米壳AI:跨境电商图片翻译的“隐形革命”:当AI技术遇上全球化生意
  • 每日算法-250430
  • 高性能架构设计-分库分表
  • 2025上海车展 | 移远通信推出自研NG-eCall QuecOpen方案,助力汽车安全新标准加速落地
  • AVPro Video加载视频文件并播放,可指定视频文件的位置、路径等参数
  • 海外社交软件开发进阶:AI驱动与高可用架构的深度实践
  • 极品工具箱 1.3.7 | 多功能合一的工具箱,涵盖音乐搜索、短视频解析等特色功能
  • 电子病历高质量语料库构建方法与架构项目(临床情景理解模块篇)
  • 【综述】相位解包裹算法对比分析
  • LVGL -按键介绍 下
  • (51单片机)LCD显示红外遥控相关数据(Delay延时函数)(LCD1602教程)(Int0和Timer0外部中断教程)(IR红外遥控模块教程)
  • 大连理工大学选修课——机器学习笔记(5):EMK-Means
  • 《软件设计师》复习笔记(10.1)——算法特性、时间复杂度、递归、分治、动态规划
  • flutter 专题 六十四 在原生项目中集成Flutter
  • 应对过度处方挑战:为药物推荐任务微调大语言模型(Xiangnan He)
  • 4.29[Q]NLP-Exp2
  • pycharm导入同目录下文件未标红但报错ModuleNotFoundError
  • 讲座|为什么要不断地翻译叶芝的诗?它们为什么值得细读?
  • 山西太原小区爆炸事故已造成17人受伤
  • 狄威已任国铁集团副总经理
  • 解放日报:这是一场需要定力和实力的“科技长征”
  • 浦发银行一季度净利175.98亿增1.02%,不良率微降
  • 160名老人报旅行团被扔服务区?张家界官方通报