python 编程入门 - 学习笔记(上篇)

前言

这段时间基本告别了摸鱼,认认真真在工作和学习上努力了一段时间,实际上这篇文章不太适合发在这里,毕竟鱼排的鱼油们个个都是高手,不然也挤不出时间摸鱼(笑~)

但是吧,自己学完的部分,总结好的笔记,放出来也更有意义

这篇笔记,是基于python编程从入门到实践(第二版)写成

得提前说明,我是个非科班,非计算机行业的,程序员,笔记上有很多幼稚的认识,请各位多多包涵,若有疏漏,请来鞭策我吧~

观前提示:python学习是基于我已有的perl知识写成,并不适合完全新手入门,有些知识点简略而过

这篇上篇,仅包含最基础的语法部分,不牵涉任何高级使用

hello,world

print("hello,world")

官网

https://www.python.org/

官方帮助文档地址

https://docs.python.org/zh-cn/

注释

# 使用#作为注释 """ 三引号之间的内容也是注释 多行注释 """

数据类型

此条目完全可以参考C语言,使用type函数可以返回数据类型

无需理解,了解即可

不同函数需要不同类型的数据

print(type("123"))
  • 字符串(str)

    若要将一个数字转换为字符串,直接在前面加str转换

    a = 4 print(str(a))
  • 整数(int)

    字符串转换为数值,使用int转换

    a = "3" a = int(a) print(a)
  • 浮点数(float)

  • 布尔类型(bool):TrueFalse

    t=True
  • 空值类型:空值并非false,就是空值,具体为None

    my_wife = None
  • 列表

  • 字典

字符串

#引号内就是字符串,也可以用单引号括住内容,不加引号就是变量 print ('test') #可以用“+”号将字符串连接(如果需要与非字符串连接,则需要使用后续的变量内插功能) print("我的"+"测试") #python特性,读一行执行一行,因此想字符串直接换行,需使用三引号,否则换行必须使用\n print('''今年是 高三一班 打扫卫生''') #字符串转义,遇到特殊符号会陷入迷惑,需要使用反斜杠‘\’转义,或在前面加入r参数 print("\\ntest_2") print(r"\ntest_2") #如字符串包含双引号,使用反斜杠,也可以使用单引号括住字符串避免歧义 print("te\"xt_1") print('tes"t_3')

特殊用法

字符串可以直接使用类似数组的方法提取字符串中的字符

可以为负值,则从后往前

print("123456"[2]) #输出的是3 print("123456"[-1]) #输出6

数字计算

python支持直接对数计算,数与运算符之间加空格不影响计算,也支持使用括号进行次序运算

print(2+3) print(3 ** 2) print((2+3)*4) print(4 % 3) #求模计算(余数) #数较大时,加入下划线使得易于阅读,也不影响计算,结果不会出现下划线 print(1_0000_0000 *5) #更多计算方式,使用函数库math #导入函数库使用import import math print(math.sin(1))

注意,只要操作数是浮点数,以及除法,得到的结果也会是浮点数

变量

变量规范

命名不得以数字开头,不允许出现空格,通常来说只允许数字,下划线,字母三种组合

python同样不允许关键字作为变量名,你可以输入help("keywords")运行,来查看哪些为python关键字

特别的,Python3.x 已经支持全面 Unicode 编码,比如支持使用中文作为变量名

定义变量

message = "Hello Python world!" print(message) old_message = message message = "Hello Python Crash Course world!" print("message值:\n"+message) print("old_message值:\n"+old_message) #同时多个变量赋值 aa,bb,cc=1,2,3 print(aa) print(bb) print(cc)

技巧

赋值变量时,若想换行,使得代码更有阅读性,则可以使用反斜杠''。表示尚未结束

aaa = "te"+\ "st888" print(aaa)

变量操作

若是想要在变量上增加内容,则可以使用+=

a = "这是" a += "继续" print(a)

变量内插

f字符串(python3.6及以上版本)

要在字符串中插入变量的值,需要使用f字符串,f是format(格式设置)的意思

基本形式f"{变量}",将花括号内的变量替换为字符串

演示代码

first_name = "ada" last_name = "lovelace" full_name = f"{first_name} {last_name}" #可以在f字符串中将普通字符串与变量混合,以及与方法进行同时使用 message = f"Hello, {full_name.title()}!" print(message) #结果为 #Hello, Ada Lovelace! #可以不赋值,直接print print (f"test,{full_name.title()}!")

format方法

对版本无要求

# 演示形式 # 如果中括号内无内容,则会顺序填入变量 full_name="{} {}".format(first_name,last_name) # 可以用数字指定是哪个变量,就能完成一个变量多次输入 full_name="{0} {1} {0}".format(first_name,last_name) # 也可以使用关键词进行绑定 full_name="{key1} {key2} {key1}".format(key1=first_name,key2=last_name)
绑定的关键词并不是变量,不会影响同名的变量

格式化

如果插入变量是浮点数,则可以在花括号内进行格式化

name = "小明" gap = 3.1234 #f字符串 print(f"{name} 你好,您的成绩是:{gap:.2f}") # format print("{0}您好,您的成绩是:{1:.2f}".format(name,gap))

比如这里用:.2f格式化为2个小数位

方法

对变量使用方法,变量与方法之间用.连接,方法后续的括号中写方法的参数

对象.方法名(..)

亦可以对字符串直接使用方法

注意,使用方法并不会修改变量原始内容

如下代码

name ="ada lobelace" print (name.title()) #print中将name变量使用方法title(首字母大写),此处title无需参数,所以()内为空 #输出结果 #Ada Lobelace #类似的 print(name.upper()) #全大写 print(name.lower()) #全小写 #想要固定下来这个结果,就重新赋值 name=name.title() #直接对字符串使用 print("lovelace".title())

删除空白

test=" a b c " print(test) #清除末尾空白 print(test.rstrip()) #清除开头空白 print(test.lstrip()) #清除两边的空白 print(test.strip())

列表

基本用法

吐槽:为什么不叫数组??

#定义一个列表,由中括号括住,单双引号无所谓 #没被引号括住的是数字 test = ['a','b',"c",'56',56] #打印某一个元素,数字是索引位置,负数是反向 print(test[1]) print(test[-2]) #组合用法 print(test[1].title()) print(f"this is {test[0]}")

索引若下标越界,会直接报错

元组

元组是不可变列表的意思,即无法修改元素

定义元组通过逗号,书上代码为了整洁性会建议加上圆括号

因此,如果需要定义单元素的元组,同样也需要一个逗号

a = 200, 50 c = (50, 60) #单元素元祖 b = 100,

虽然无法修改元素,但重新定义元组是合法的

t_a = (3, 4, 5) t_a = 3,5,7 print(t_a)

即使元组内元素是变量,在外部修改变量也不会改变元组的元素

但是,如果是列表,则内部依然会变

列表操作

与上述变量不同,列表属于可变,使用方法会直接改变列表本身

增添改删

#直接对索引赋值即为修改该索引值 test[1]="d" print(test) #添加到末尾,直接使用方法append,且无需赋值操作 test.append("t") print(test) #插入元素,方法insert,指定位置 test.insert(1,"k") print(test) #删除元素 ## del函数,直接删除 del test[0] ## pop方法,提取出1个元素,参数可以指定元素索引,留空则为末尾 test_p=test.pop() print(test) print(test_p) test_p=test.pop(1) ## remove方法,匹配删除元素,可以由变量指定,注意若重复则只匹配一次,需要使用循环 test.remove("a") no_c = "c" test.remove(no_c)

排序

#sort方法,按字母顺序排序,改变列表 test.sort() print(test) ##加参数,反向排序 test.sort(reverse=True) #sorted方法,临时排序,不改变列表 print(sorted(test)) ##同样接受反向排序的参数 print(sorted(test,reverse=True))

其他操作

#reverse方法,反转列表 test.reverse() print(test) #len函数,获取列表长度,长度从1开始计数 print(len(test))

for循环遍历

循环可以对列表,字符串,字典等操作

对字符串操作则是依次遍历每一个字符(不用像perl一样split后做成数组输出,很方便)

#结构 for (取出的值赋值临时变量) in (列表名) : ...(缩进部分代码表示循环框架内语句) (非缩进则表示在循环外)

注意临时变量不会在循环结束后自动删除,而是继续保留为最后一次被赋值的值

#定义列表 test = ['a','b','c',"56"] #遍历输出 for test_a in test: print(test_a)

列表解析(for循环单行式存储列表)

对一个列表内所有内容进行相同修改,并存储为一个新的列表,可以快捷的使用单行式for

结构为

新列表名 = [(待存储的临时变量及所需操作) for (临时变量) in (列表)]

示例代码

#对数字操作 t_a=[1,2,3] aa = [tt+1 for tt in t_a] print(aa) #对字符串操作 t_b=['a','b','c',"56"] bb = [f"{tb}test" for tb in t_b] print(bb)

创建连续列表

使用range函数构建一个连续数字,注意不会显示大于或等于第二位参数的数,例如range(1,6),输出是1-5

for t in range(1,6): print(t)

可以将其固定为列表,需要函数list

te=list(range(1,3)) for tea in te: print(tea)

range函数支持指定步长,即间隔,由第三位参数指定

for tea in range(1,9,2): print(tea)

数学操作

#max与min函数,返回列表最大/最小值/和 test = list(range(1,25)) print(max(test)) print(min(test)) print(sum(test))

切片

输出部分列表(也支持字符串变量)内容,指定索引范围,注意,索引同样不能等于或大于终止索引序号

索引也允许使用负数

切片形式可以在任意地方使用,例如for循环

t = ['a', 'b', 'c', "56"] print(t[0:2]) #起始索引可以不指定,默认从头开始 print(t[:3]) #终止索引也可以不指定,一直输出到末尾 print(t[1:]) #负数索引 print(t[-2:]) #始终输出最后2位

同样的,切片也能指定步长,由第三位参数指定

示例如下

t = ['a', 'b', 'c', "d",'f','g'] print(t[0:5:2])

列表复制

区分浅拷贝与深拷贝,是由于列表中的嵌套导致的区别

由于嵌套在列表中是以地址指向的信息存在,因此浅拷贝只能拷贝这个地址信息,而不能使其独立存在,顾名思义,修改嵌套的内容,会同时生效

非拷贝(别名)

注意这种方法并不是拷贝,修改其中一个列表,也会对另一个列表产生影响

可以认为是对旧列表起了个别名,实际都是同一个列表

t = ['a', 'b', 'c', "d",'f','g'] a = t t.insert(2,'3') print(t) print(a)

浅拷贝(无法影响嵌套)

几种方法等效

copy方法

a = [1,2,[3,4]] b = a.copy() print("a:",a) print("b:",b) print("第一次改变:") a[1] = 666 print("a:",a) print("b:",b) print("第二次改变:") a[2][0] = 777 print("a:",a) print("b:",b) ##输出 a: [1, 2, [3, 4]] b: [1, 2, [3, 4]] 第一次改变 a: [1, 666, [3, 4]] b: [1, 2, [3, 4]] 第二次改变 a: [1, 666, [777, 4]] b: [1, 2, [777, 4]]

切片方式

t = ['a', 'b', 'c', "d",'f','g'] b=t[:] print(b)

list赋值

a = [1,2,[3,4]] b = list(a)

以及包括,列表解析,for循环

深拷贝

deepcopy函数

import copy a = [1,2,[3,4]] b = copy.deepcopy(a)

判断

在Python中,None、任何数值类型中的0、空字符串“”、空元组()、空列表[]、空字典{}都被当作False,还有自定义类型,如果实现了  __ nonzero __ () 或 __ len __ () 方法且方法返回 0 或False,则其实例也被当作False,其他对象均为True。

符号

#比较运算符 == 相等 != 不等 > 大于 < 小于 >= 大于等于 #特殊 not 判断反向仅用于后续的一次运算可用括号括起来整体反向 ##示例代码 a = 6 if not a > 5: print("goo" * 3) else: print("nno") #判断多个条件,可以多个叠加 and 两个条件满足 or 任意一个条件满足 #其他符号 in 判断元素是否在列表中 not in 判断元素是否不在列表中 ##示例代码 a = ['a', 'b', 'c', 'd', 'e'] if 'c' in a: print("good")

and or多重混合的解释

优先级关系:

not > and > or

可以使用括号改变

基础

下面是最简单的逻辑运算: 这里 1,2 都是Ture; 0,‘’都是False

1 and 2 ==> 2 1 or 2 ==> 1

1 and 0 ==> 0 1 or 0 ==> 1

0 and 1 ==> 0 0 or 1 ==> 1

0 and '' ==> 0 0 or '' ==> ''

总结:

or 从左到右,返回第一个为真的值,都为假返回后一个值

and 从左到右,若所有值均为真,则返回后一个值,有一个假的值,则返回第一个假的值

混合形式-短路逻辑

不推荐混合写法,复杂难懂,也不利于后续维护

逻辑运算符 and / or 一旦不止一个,其运算规则的核心思想就是短路逻辑。好的,那我们就来了解一下短路思想:

表达式从左至右运算,若 or 的左侧逻辑值为 True ,则短路 or 后所有的表达式(不管是 and 还是 or),直接输出 or 左侧表达式 。

表达式从左至右运算,若 and 的左侧逻辑值为 False ,则短路其后所有 and 表达式,直到有 or 出现,输出 and 左侧表达式到 or 的左侧,参与接下来的逻辑运算。

若 or 的左侧为 False ,或者 and 的左侧为 True 则不能使用短路逻辑

if形式

#布尔式 if [条件]: ...(执行代码) ##示例 a = True if a: print("good") #条件式(本质是一样的,条件式解出布尔值交给if判断) if (待判断对象) (判断符) '(判断值)': (缩进)...(执行代码) ##示例 a = ['a', 'b', 'c', 'd', 'e'] for aa in a: if aa == 'c': print(aa.title())

与perl不同,不能直接对未定义变量判断

在python中,可用多种方法,其一是使用dir()获取定义变量列表,然后使用if判断

注意,是以字符串(变量名)形式判断,不能直接使用变量

print(dir()) if 'b' in dir(): print("good")

if-else

else语句为判断失败后执行

if 'b' in dir(): print("good") else: print("这个变量未定义")

if-elif-if

检查多种形式,对应不同情况,elif可以无限叠加

基本形式

b = 4 if 'b' not in dir(): print("这个变量未定义") elif b < 5: print("b小于5") else: print("b是其他值")

为了使判断更为安全,最后的else可以省略,以使判断不会出现意外情况

match-case(>3.10)

类似c语言的switch-case语句,无需反复if,else,根据不同的值执行对应的代码块

match 后的对象会依次与 case 后的内容进行匹配,如果匹配成功,则执行匹配到的表达式,否则直接跳过,_ 可以匹配一切,亦即是c语言的default

匹配内容较为复杂,见后续,这里仅描述判断语句

示例如下

b = 4 match b: case 5: print("b等于5") case 3|4: print("b是3或4") case _: print("b未知")

使用|符号可以一次性匹配多种结果

集合

概念

集合的概念是一个无序不重复元素集,即使在创建时有重复,最终存储的也是无重复的

创建集合的方法,是用花括号包裹

可以理解为无重复列表,区别是输出的时候顺序是随机的

aa = {'a','b','c','a'} print(aa)

可以使用set函数来转换为集合,自动进行去重处理

集合操作

添加元素

set 集合中添加元素,可以使用 set 类型提供的 add() 方法实现,该方法的语法格式为:

setname.add(element)

其中,setname 表示要添加元素的集合,element 表示要添加的元素内容。

需要注意的是,使用 add() 方法添加的元素,只能是数字、字符串、元组或者布尔类型(True 和 False)值,不能添加列表、字典、集合这类可变的数据,否则 Python 解释器会报 TypeError 错误。例如:

a = {1,2,3} a.add((1,2)) print(a) # {(1, 2), 1, 2, 3} a.add([1,2]) # 报错 print(a)

删除元素

删除现有 set 集合中的指定元素,可以使用 remove() 方法,该方法的语法格式如下:

setname.remove(element)

使用此方法删除集合中元素,需要注意的是,如果被删除元素本就不包含在集合中,则此方法会抛出 KeyError 错误,例如:

a = {1,2,3} a.remove(1) print(a) #{2, 3} a.remove(1) #报错 print(a)

上面程序中,由于集合中的元素 1 已被删除,因此当再次尝试使用 remove() 方法删除时,会引发 KeyError 错误。

如果我们不想在删除失败时令解释器提示 KeyError 错误,还可以使用 discard() 方法,此方法和 remove() 方法的用法完全相同,唯一的区别就是,当删除集合中元素失败时,此方法不会抛出任何错误。

a = {1,2,3} a.remove(1) print(a) #{2, 3} a.discard(1) print(a) #{2, 3}

集合运算

集合最常做的操作就是进行交集、并集、差集以及对称差集运算

img

上图中,有 2 个集合,分别为 set1={1,2,3} 和 set2={3,4,5},它们既有相同的元素,也有不同的元素。以这两个集合为例,分别做不同运算的结果如表 1 所示。

运算操作 Python运算符 含义 例子
交集 & 取两集合公共的元素 >>> set1 & set2 {3}
并集 | 取两集合全部的元素 >>> set1 | set2 {1,2,3,4,5}
差集 - 取一个集合中另一集合没有的元素 >>> set1 - set2 {1,2} >>> set2 - set1 {4,5}
对称差集 ^ 取集合 A 和 B 中不属于 A&B 的元素 >>> set1 ^ set2 {1,2,4,5}

字典

即perl语言中的哈希

字典是一系列的键值对,键与值一一对应

键必须是不可变数据类型,如字符串,数值,元组,等

元组可以实现多个属性描述一个值,比如张三,53岁

可以做更加精确的指向

值可以是任意,比如数,字符串, 列表,或者也可以是字典

与perl不同的是,使用for循环遍历,存储于字典中的键顺序不会变

可以理解字典为存储一系列的变量的列表

定义字典

用花括号包裹,引号包裹内容,单双引号均可,键值对使用冒号对应,不同键值对之间是逗号

输出内容则使用中括号,内部用引号包裹的任意一个键内容即可

注意与集合的区别,如果花括号内没有键值对,则被认为是集合

alias_0 = {'color':'red','point':'5'} print(alias_0['color']) # 遍历输出 for aa in alias_0: print(aa + "\t" + alias_0[aa])

可以换行,注意缩进

user_0 = { 'username': 'efermi', 'first': 'enrico', 'last': 'fermi', } print(user_0)

输出不存在的键会直接报错,可以使用方法get,使得不存在值时返回一个默认值

第一个参数是键,第二个参数是默认返回值,如果未指定第二个参数,则会默认返回None,意指空值

user_0 = { 'username': 'efermi', 'first': 'enrico', 'last': 'fermi', } print(user_0.get("2", "没有这个值"))

键值对操作

获取键值对数量的方法,可用len函数

user_0 = { 'username': 'efermi', 'first': 'enrico', 'last': 'fermi', } print(len(user_0))

添加

类似数组,直接定义一个键等于值即可,但必须已经先存在字典(可以创建一个空字典)

alias_0 = {} alias_0["bb"] = 3

注意,如果已经定义了同名列表,则不能作为字典添加键值对

不同的是,数字下标可以不加引号即可添加

如果已经定义了字典,那么做类似操作列表索引的操作是被视作添加键值对

alias_0 = {"color": "red", "point": "5"} print(alias_0) alias_0["bb"] = 3 print(alias_0) alias_0[2] = 6 print(alias_0)

修改

如同添加键值对一样,对一个键赋值,即可修改

若要检查键是否存在,可以使用in进行检查,这个表达式返回的值是布尔值

user_0 = { 'username': 'efermi', 'first': 'enrico', 'last': 'fermi', } print("last" in user_0)

示例(书上源码)

# 定义一个物体的属性,根据速度决定移动距离 alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'} print(f"Original position: {alien_0['x_position']}") # 检查速度决定移动距离 if alien_0['speed'] == 'slow': x_increment = 1 elif alien_0['speed'] == 'medium': x_increment = 2 else: x_increment = 3 # 新位置是旧位置加移动距离 alien_0['x_position'] = alien_0['x_position'] + x_increment print(f"New position: {alien_0['x_position']}")

删除

同列表一样,使用del语句

alien_0 = {'x_position': 0, 'y_position': 25, 'speed': 'medium'} print(alien_0) del alien_0["speed"] print(alien_0)

遍历

基本

a = { "age": 4, "year": "2022", "name": "ge" } for key, value in a.items(): # 注意必须使用f函数输出,因为“+”只能用于字符串的连接 # 而字典的键值都有可能是别的数值类型 print(f"键:{key}") print(f"值:{value}")

方法items返回字典的键值对的一个元组

与perl不同的是,如果for循环中只赋值给一个值,那么输出的并不只是键,而是包含单独这个键与值的元组

for b in a.items(): print(b[0]) print(f"{b[1]}\n")

单独键或值

方法keys可以只返回字典中的键

for k in a.keys(): print("键:"+ k)

for循环字典时默认输出的就是键

因此可以省略这个方法

for k in a: print("键:"+ k)

这个方法实际上是返回了包含整个字典的键的列表,所以可以用来检查某个键是否在字典中

if "k" not in a.keys(): print("不存在")

方法values可以只返回字典中的值

for b in a.values(): print(f"这是{b}")

如果值发生重复,那么会输出许多无意义的重复

如果要剔除重复,筛选出非重复项的值,则可用set函数,创建一个集合

a = { "age": "4", "year": "2022", "name": "ge", "aaa":"ge" } for b in set(a.values()): print(f"这是{b}")

遍历顺序

因为keys返回的是一个列表,因此同样可以使用列表的方式进行排序后输出,比如sorted函数

a = { "age": "4", "year": "2022", "name": "ge" } for b in sorted(a.keys()): print(f"这是{b}")

嵌套

字典存储在列表中

基本形式

alien_0 = {'color': 'green', 'points': 5} alien_1 = {'color': 'yellow', 'points': 10} alien_2 = {'color': 'red', 'points': 15} aliens = [alien_0, alien_1, alien_2] for alien in aliens: print(alien)

可以以匿名形式

aliens = [] for alien_number in range(30): new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'} aliens.append(new_alien) for alien in aliens[:5]: print(alien) print(f"Total number of aliens: {len(aliens)}")

修改匿名的嵌套字典,则可以用循环赋值

for alien in aliens[:3]: if alien['color'] == 'green': alien['color'] = 'yellow' alien['speed'] = 'medium' alien['points'] = 10 for alien in aliens[:5]: print(alien)

列表存在字典中

pizza = { 'crust': 'thick', 'toppings': ['mushrooms', 'extra cheese'], } print(pizza['toppings'][1])

多维字典 - 字典存在字典中

users = { 'aeinstein': { 'first': 'albert', 'last': 'einstein', 'location': 'princeton', }, 'mcurie': { 'first': 'marie', 'last': 'curie', 'location': 'paris', }, } print(users["mcurie"]["last"])

输入

函数input

input之后,这个变量就会被输入的内容所替代(只是作为一个提示信息存在)

message = input("请输入并按回车键确认: ") print(message) # 被替换了 print(message)

注意input输入的是字符串,若要对输入的数值进行计算,则需要使用int进行转换

age = input("How old are you? ") age = int(age) # 这里其实可以省略写法 age = int(input("How old are you? ")) if age >= 18: print("good")

多行形式

message = "请输入内容," message += "\n并按回车键确认: " message = input(message) print(message)

循环

for循环

见列表中的小节,for循环遍历

适用于有明确循环次数时使用

while循环

适用于在==没有==明确循环次数时使用

基本形式

满足条件时退出循环

while 条件A: 行动B
image-20230212214451529

示例

current_number = 1 while current_number <= 5: print(current_number) current_number += 1

循环输入

prompt = "输入一些东西,我将重复你的话:" prompt += "\n输入 'quit' 退出. \n" # 必须先定义,否则无法判断不存在的变量 message = "" while message != 'quit': message = input(prompt) if message != 'quit': print(message + "\n")

结束循环的方式

这是接下来代码的前面部分

prompt = "输入一些东西,我将重复你的话:" prompt += "\n输入 'quit' 退出. \n" message = ""

使用标志来简化循环判断

可以使一个标志来代表所有的判断条件,否则while的条件会很复杂

... active = True while active: message = input(prompt) if message == 'quit': active = False else: print(message +"\n")

退出当次循环 - continue语句

执行之后,后面的语句不再执行,而是直接进入下一循环

# 这个示例只会输出不能被2整除的数(奇数) current_number = 0 while current_number < 10: current_number += 1 if current_number % 2 == 0: continue print(current_number)

退出整个循环 - break语句

立即退出循环,适用于所有循环,只能跳出一层循环

... while True: # True就是这个循环条件永远成立 message = input(prompt) if message == 'quit': break else: print(message+"\n")

使用while处理列表和字典

列表

有内容的列表是Ture,空列表是False

示例

# 将一个列表中的数据经过验证后逐个转移到另一个列表 unconfirmed_users = ['alice', 'brian', 'candace'] confirmed_users = [] while unconfirmed_users: current_user = unconfirmed_users.pop() print(f"验证用户: {current_user.title()}") confirmed_users.append(current_user) print("\n以下用户已确认:") for confirmed_user in confirmed_users: print(confirmed_user.title())

删除列表中存在的所有指定值(remove只能删除一次)

pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat'] print(pets) while 'cat' in pets: pets.remove('cat') print(pets)

字典

示例

responses = {} while True: name = input("你的名字是?\n") question = input("你喜欢的语言是什么?\n") responses[name] = question repeat = input("还有人接受调查吗?输入'no'退出\n") if repeat == "no": break print("调查结束\n") for name , response in responses.items(): print(f"{name}喜欢的语言是{response}")

函数

基本结构

很明显,这是C语言的函数概念,类似perl中的子程序(不同的是,函数必须写在调用之前)

自定义一个函数,用于代码的反复执行,特点是固定的输入则有着固定的输出

函数应该保持一种理念,即每一个函数只负责一项具体工作

一个示例

def greet_user(): # 函数内容 print("Hello!") greet_user()

第一行解析:

  • def 表示定义函数(与perl不同,函数名必须小写)
  • greet_user是函数名,后面的括号是接受参数的部分,空则代表无需任何参数即可执行,后续再看
  • :结尾

这个示例函数无需任何参数,一旦调用就会打印Hello!

变量的作用域

全局变量

在函数外定义的变量就是全局变量,在函数中可以被直接读取

a = 5 # 全局变量 print(id(a)) def func(): print(a) print(id(a)) ''' 94648897326528 5 94648897326528 '''

id() 函数返回对象的唯一标识符,标识符是一个整数。

实际上是对象的内存地址

局部变量

在函数中,可以使用与全局变量相同的变量名,默认为局部变量

局部变量被改变不会影响同名全局变量的值

a = 5 # 全局变量 def func(): a=5 a=a+1 # 6 print(a) func() print(a) ''' 6 5 '''

在函数中修改全局变量

因此,为了避免混淆,在函数中不能直接修改全局变量的值,必须使用global语句标明其为全局变量

a = 5 # 全局变量 def func(): global a a=a+1 # 6 func() print(a) ''' 6 '''

不能使一个变量名在函数中又当局部变量又是全局变量

传入参数

基本形式

def greet_user(username): print(f"Hello, {username.title()}!") greet_user('jesse')

这个函数拥有一个变量接收参数信息,写在括号中即可

实参与形参

在定义函数的括号中,接收参数的变量被称为 形参

与之对应的,在调用函数时,写在函数参数括号中的变量被称为 实参

代码规范提示:

如果一次性使用了多个形参,使得一行特别长,则在左括号打完之后,回车,并前置按两个tab键

IDE会帮你操作,但自己注意,如下所示

def function_name( parameter_0, parameter_1, parameter_2, parameter_3, parameter_4, parameter_5):

参数调用方式

位置实参

按照传入实参的顺序,依次放入形参中

例如:

def describe_pet(animal_type, pet_name): print(f"\nI have a {animal_type}.") print(f"My {animal_type}'s name is {pet_name.title()}.") describe_pet('hamster', 'harry') describe_pet('dog', 'willie')

关键字实参

将形参作为关键词使用,将实参与关键词绑定,无需考虑顺序

例如

def describe_pet(animal_type, pet_name): print(f"\nI have a {animal_type}.") print(f"My {animal_type}'s name is {pet_name.title()}.") describe_pet(animal_type='hamster', pet_name='harry')

参数默认值

形参可以设置默认值,如在未接受实参的传入时使用默认值

默认值必须绑定关键词

def describe_pet(animal_type='dog'): print(f"\nI have a {animal_type}.") describe_pet(animal_type='mouse') describe_pet()

上述代码,若不传入animal_type,则默认为dog

可以使得默认值为空,让这个参数变为可选项,如下所示

def get_formatted_name(first_name, last_name, middle_name=''): if middle_name: full_name = f"{first_name} {middle_name} {last_name}" else: full_name = f"{first_name} {last_name}" print(full_name) get_formatted_name('jimi', 'hendrix') get_formatted_name('john', 'hooker', 'lee')

总结 - 混合调用

上述三种参数调用形式可以混合使用

例如

def tes (test1, test2, tt="默认", gg="g"): print(f"这是测试{test1},这是{tt},这是测试{test2},这是g{gg}") tes("1", test2="22", gg="3") tes("1", "22", , gg="3")

规则如下

  • 默认形参(函数中接受传入参数的变量)后面不允许出现非默认形参,所以必须将默认形参全部放在后面
  • 位置实参(函数调用时的参数)必须在所有绑定了关键词实参的前面
  • 默认形参同样接收位置实参的传入

虽然怎么样都可以,但不要写的太复杂

返回值

就是没有直接输出的函数,有助于代码模块化

与perl不同,默认返回为None,空值,因此必须使用return语句指定函数的返回值

返回一个字符串

def get_formatted_name(first_name, last_name): full_name = f"{first_name} {last_name}" return full_name.title() musician = get_formatted_name('jimi', 'hendrix') print(musician)

返回一个字典

def build_person(first_name, last_name): person = {'first': first_name, 'last': last_name} return person musician = build_person('jimi', 'hendrix') print(musician["first"])
def build_person(first_name, last_name, age=None): person = {'first': first_name, 'last': last_name} if age: person['age'] = age return person musician = build_person('jimi', 'hendrix', age=27) print(musician)

传递列表

基本示例

def greet_users(names): for name in names: msg = f"Hello, {name.title()}!" print(msg) usernames = ['hannah', 'ty', 'margot'] greet_users(usernames)

列表的变与不变

在函数中,对列表的修改是永久的

def print_models(unprinted_designs, completed_models): while unprinted_designs: current_design = unprinted_designs.pop() print(f"Printing model: {current_design}") completed_models.append(current_design) def show_completed_models(completed_models): print("\nThe following models have been printed:") for completed_model in completed_models: print(completed_model) unprinted_designs = ['phone case', 'robot pendant', 'dodecahedron'] completed_models = [] print_models(unprinted_designs, completed_models) show_completed_models(completed_models) show_completed_models(unprinted_designs)

可以让实参是列表的切片形式,这样就不会改动列表了

比如

function_name(list_name[:])

上面的列表想保留则如下

print_models(unprinted_designs[:], completed_models)

变长参数

核心思想与perl相同,将参数收入一个数组中

在python中的实现和形式略有不同,是将其收入元组中,且参数需要用*星号标记

def make_pizza(*toppings): print(toppings) for topping in toppings: print(f"- {topping}") make_pizza('pepperoni') make_pizza('mushrooms', 'green peppers', 'extra cheese')

注意,这同样需要作为形参位置的规则,收入任意数量的形参必须在位置形参和关键字形参之后

def make_pizza(size, *toppings): print(f"\nMaking a {size}-inch pizza with the following toppings") for topping in toppings: print(f"- {topping}") make_pizza(16, 'pepperoni') make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

特别的,python可以接收字典的键值对

由于接受参数的形参需要特别标记,同理,若想将其收入字典中,则需要两颗星标记形参**,表明为字典

示例

def build_profile(first, last, **user_info): user_info['first_name'] = first user_info['last_name'] = last return user_info user_profile = build_profile('albert', 'einstein', location='princeton', # 直接传入键值对,存入user_info field='physics') print(user_profile)

模块

写好的函数可以放在模块中(独立的文件),只有在导入时调用,使得代码更加简洁清晰,易于分享

模块文件的扩展名为py

创建/导入模块

基本示例

调用模块的基本命令,import 模块名

将函数放入模块中调用,如下所示

  1. 模块文件,文件名pizza.py
def make_pizza(size, *toppings): """概述要制作的比萨。""" print(f"\nMaking a {size}-inch pizza with the following toppings:") for topping in toppings: print(f"- {topping}")
  1. 主程序
import pizza pizza.make_pizza(16, 'pepperoni') pizza.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

Python读取这个文件时,代码行import pizza 让Python打开文件pizza.py,并将其中的所有函数都复制到这个程序中

要调用被导入模块中的函数,可指定被导入模块的名称 pizza 和函数名 make_pizza() ,并用句点分隔

指定导入特定函数

语法 - from (模块名) improt (函数名),函数名可以有多个,用逗号分割

例如基本示例中的模块

from pizza import make_pizza make_pizza(16, 'pepperoni') make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

使用这种方式导入的函数,无须使用句点语句,函数名是显式的,因此使用也可以直接用

可以一次性导入全部函数,使用*号,注意这种用法是有危险的,特别是你不清楚的别人的模块,因为会覆盖已有程序的函数或变量

from pizza import *

函数别名

考虑到导入的函数可能与程序中发生冲突,或太长,可指定别名,使用as关键字

语法 - from (模块名) improt (函数名) as (函数别名)

例如

from pizza import make_pizza as mp mp(16, 'pepperoni') mp(12, 'mushrooms', 'green peppers', 'extra cheese')

模块别名

as也可以给模块指定别名

语法 - import (模块名) as (模块别名)

示例

import pizza as p p.make_pizza(16, 'pepperoni') p.make_pizza(12, 'mushrooms', 'green peppers', 'extra cheese')

   
  • 摸鱼周报

    每周五的摸鱼派活动-摸鱼周报 发表你的每周总结

    308 引用