python 编程入门 - 学习笔记(上篇)
前言
这段时间基本告别了摸鱼,认认真真在工作和学习上努力了一段时间,实际上这篇文章不太适合发在这里,毕竟鱼排的鱼油们个个都是高手,不然也挤不出时间摸鱼(笑~)
但是吧,自己学完的部分,总结好的笔记,放出来也更有意义
这篇笔记,是基于python编程从入门到实践(第二版)写成
得提前说明,我是个非科班,非计算机行业的,程序员,笔记上有很多幼稚的认识,请各位多多包涵,若有疏漏,请来鞭策我吧~
观前提示:python学习是基于我已有的perl知识写成,并不适合完全新手入门,有些知识点简略而过
这篇上篇,仅包含最基础的语法部分,不牵涉任何高级使用
hello,world
print("hello,world")
官网
官方帮助文档地址
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):
True
和False
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}
集合运算
集合最常做的操作就是进行交集、并集、差集以及对称差集运算
上图中,有 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
示例
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 模块名
将函数放入模块中调用,如下所示
- 模块文件,文件名
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}")
- 主程序
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')
-
摸鱼周报
每周五的摸鱼派活动-摸鱼周报 发表你的每周总结
阅
😄 因为我不是一班的呀
不错不错~再讲讲装饰器和迭代器吧
学会了是不是就可以写脚本了
可以啊,有这些基础就可以写一个完整的功能性比较强的脚本了
~~😭还没打小怪呐
那难不难阿
很棒很棒!!!学习学习!!!
牛逼
争取早日成为py大手子,然后抱大腿
让我狠狠的查漏补缺了一顿!!想听听装饰器
还真有帮助啊,haha,我后面学会了再发😂
收藏加关注用处挺大的
收藏了,大佬什么时候更新下篇
大佬
不是大佬😂
由于我更擅长perl,对python是个平替,深入学习的收益不大,我现在改学R了,等我R学完了再发下篇
风白太厉害了,这不奖励自己一下吗?
不厉害不厉害,都是基础