Pycharm快捷键
1.移动到本行开头:home键
2.移动到本行结尾:end键盘
3.注释代码:ctrl+/
4.重命名变量:shift+f6
5.Debug F8逐过程—调试不进入方法
6.ctrl+P 查看函数参数信息
7.ctrl+Q 查看函数注释
F7逐语句----进入方法
8.三双引号注释回车会自动换行,三单引号注释回车不会换行
Python变量内存
变量名是真是内存地址的别名,变量名地址内存放对象的地址
如name=“abc”
中name的地址是0x101,‘abc’的地址是0x999,name地址存的内容是abc的地址0x999
只要是变量的赋值给的都是内容的地址, a=b=“we” ,a.b存的内容都是"we"的地址
随机函数random
Python产生随机数:
一.Python自带的random库
1.参生n--m范围内的一个随机整数: random.randint(n,m)
2.产生0到1之间的浮点数: random.random()
3.产生n---m之间的浮点数: random.uniform(1.1,5.4)
4.产生从n---m-1间隔为k的整数: random.randrange(n,m,k)
5.从序列中随机选取一个元素: random.choice([1, 2, 3, 4, 5, 6, 7, 8, 9, 0])
6.在一些特殊的情况下可能对序列进行一次打乱操作: random.shuffle([1,3,5,6,7])
二.numpy库
1.产生N维的均匀分布的随机数: np.random.rand(d1,d2,d3,…,dn)
2.产生n维的正态分布的随机数: np.random.randn(d1,d2,d3,...,dn)
3.产生n--m之间的k个整数:np.random.randint(n,m,k)
4.产生n个0--1之间的随机数: np.random.random(10)
5.从序列中选择数据: np.random.choice([2,5,7,8,9,11,3])
6.把序列中的数据打乱:np.random.shuffle(item)
import numpy as np
#产生n维的均匀分布的随机数
print(np.random.rand(5,5,5))
#产生n维的正态分布的随机数
print(np.random.randn(5,5,5))
#产生n–m之间的k个整数
print(np.random.randint(1,50,5))
#产生n个0–1之间的随机数
print(np.random.random(10))
#从序列中选择数据
print(np.random.choice([2,5,7,8,9,11,3]))
#把序列中的数据打乱
#np.random.shuffle(item) 不会参数返回值,改变的话是在原列表中修改的
item = [2,5,7,8,9,11,3]
np.random.shuffle(item)
print(item)
对齐输出
mat = "{:20}\t{:28}\t{:32}"
print(mat.format("占4个长度","占8个长度", "占12长度"))
#如果需要居中输出在宽度前面加一个^
mat = "{:^20}\t{:^28}\t{:^32}"
print(mat.format("占4个长度","占8个长度", "占12长度"))
占4个长度 占8个长度 占12长度
占4个长度 占8个长度 占12长度
往往要对输出内容进行对齐,看起来更清爽。
python中对齐有两种方式。
第一种是用格式符,如下:
s1 = 'long long long .'
s2 = 'short.'
print ('%-30s%-20s' %(s1,s2)) #'%-30s' 含义是 左对齐,且占用30个字符位
print ('%-30s%-20s' %(s2,s1))
long long long . short.
short. long long long .
第二种是用format,如下:
s1 = 'long long long .'
s2 = 'short.'
print ('{:>30}{:>20}' .format(s1,s2)) #{:30d}含义是 右对齐,且占用30个字符位
print ('{:<30}{:<20}' .format(s1,s2)) #{:<30d}含义是 左对齐,且占用30个字符位
print ('{:^30}{:^20}' .format(s1,s2)) #{:^30d}含义是 居中对齐,且占用30个字符位
long long long . short.
long long long . short.
long long long . short.
交换变量
a=10
b=20
a,b=b,a
print(a,b)#20 10
数据类型
空值对象None
整形
浮点型
Python中实现控制小数点位数的方法
一、利用python内置的round()函数
round()如果只有一个数作为参数,不指定位数的时候,返回的是一个整数,而且是最靠近的整数
一般情况是使用四舍五入的规则,但是碰到舍入的后一位为5的情况,如果取舍的位数前的数是偶数,则直接舍弃,如果奇数这向上取舍
二、利用格式化方法
特殊情况需要注意的和 round 方法一样
三、利用 math 模块里 ceil 和 floor 方法
math模块的ceil(x):取大于或者等于x的最小整数
math模块的floor(x):取小于或者等于x的最大整数
四、超过17位的精度分析
python默认的是17位精度,也就是小数点后16位,但是这里有一个问题,就是当我们的计算需要使用更高的精度(超过16位小数)的时候该怎么做呢?
高精度使用decimal模块,配合getcontext
decimal 模块默认精度是17位,可以通过修改 getcontext().prec 修改精度的值
字符串
-
python中单引号和双引号使用完全相同。
-
使用三引号(’’’ 或 “”")可以指定一个多行字符串。
-
转义符 **
-
反斜杠可以用来转义,使用r可以让反斜杠不发生转义。。 如 r"this is a line with \n" 则\n会显示,并不是换行。
-
按字面意义级联字符串,如"this " "is " "string"会被自动转换为this is string。
-
字符串可以用 + 运算符连接在一起,用 * 运算符重复。
-
Python 中的字符串有两种索引方式,从左往右以 0 开始,从右往左以 -1 开始。
-
Python中的字符串不能改变。
-
Python 没有单独的字符类型,一个字符就是长度为 1 的字符串。
-
字符串的截取的语法格式如下:变量[头下标:尾下标:步长]
-
f-string格式可以使字符串和数字变量相加
f-string 格式化字符串以 f 开头,后面跟着字符串,字符串中的表达式用大括号 {} 包起来,它会将变量或表达式计算后的值替换进去,实例如下:用了这种方式明显更简单了,不用再去判断使用 %s,还是 %d。
input返回的是字符串,如果input输入的是数字,返回的是字符串类型的数字,要使用这个数字进行运算需要做数据类型
复数
布尔
运算符
算术运算符
增强(赋值)运算符
以下假设变量a为10,变量b为20:
运算符 | 描述 | 实例 |
---|---|---|
= | 简单的赋值运算符 | c = a + b 将 a + b 的运算结果赋值为 c |
+= | 加法赋值运算符 | c += a 等效于 c = c + a |
-= | 减法赋值运算符 | c -= a 等效于 c = c - a |
*= | 乘法赋值运算符 | c *= a 等效于 c = c * a |
/= | 除法赋值运算符 | c /= a 等效于 c = c / a |
%= | 取模赋值运算符 | c %= a 等效于 c = c % a |
**= | 幂赋值运算符 | c **= a 等效于 c = c a |
//= | 取整除赋值运算符 | c //= a 等效于 c = c // a |
赋值运算符实例:
a = 21
b = 10
c = 0
c = a + b
print ("1 - c 的值为:", c)
c += a
print ("2 - c 的值为:", c)
c *= a
print ("3 - c 的值为:", c)
c /= a
print ("4 - c 的值为:", c)
c = 2
c %= a
print ("5 - c 的值为:", c)
c **= a
print ("6 - c 的值为:", c)
c //= a
print ("7 - c 的值为:", c)
实例输出结果:
1 - c 的值为: 31
2 - c 的值为: 52
3 - c 的值为: 1092
4 - c 的值为: 52.0
5 - c 的值为: 2
6 - c 的值为: 2097152
7 - c 的值为: 99864
Python位运算符
按位运算符是把数字看作二进制来进行计算的。Python中的按位运算法则如下:
下表中变量 a 为 60,b 为 13二进制格式如下:
a = 0011 1100
b = 0000 1101
-----------------
a&b = 0000 1100
a|b = 0011 1101
a^b = 0011 0001
~a = 1100 0011
运算符 | 描述 | 实例 |
---|---|---|
& | 按位与运算符:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0 | (a & b) 输出结果 12 ,二进制解释: 0000 1100 |
| | 按位或运算符:只要对应的二个二进位有一个为1时,结果位就为1。 | (a | b) 输出结果 61 ,二进制解释: 0011 1101 |
^ | 按位异或运算符:当两对应的二进位相异时,结果为1 | (a ^ b) 输出结果 49 ,二进制解释: 0011 0001 |
~ | 按位取反运算符:对数据的每个二进制位取反,即把1变为0,把0变为1。~x 类似于 -x-1 | (~a ) 输出结果 -61 ,二进制解释: 1100 0011, 在一个有符号二进制数的补码形式。 |
<< | 左移动运算符:运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0。 | a << 2 输出结果 240 ,二进制解释: 1111 0000 |
>> | 右移动运算符:把">>“左边的运算数的各二进位全部右移若干位,”>>"右边的数指定移动的位数 |
比较运算符
逻辑运算符
与 and A and B
如果A是false,就不在执行B
或 or A or B
如果A是true,就不再执行B
非 not
成员运算符
运算符 | 描述 | 实例 |
---|---|---|
in | 如果在指定的序列中找到值返回 True,否则返回 False。 | x 在 y 序列中 , 如果 x 在 y 序列中返回 True。 |
not in | 如果在指定的序列中没有找到值返回 True,否则返回 False。 | x 不在 y 序列中 , 如果 x 不在 y 序列中返回 True。 |
身份运算符
身份运算符用于比较两个对象的存储单元
运算符 | 描述 | 实例 |
---|---|---|
is | is 是判断两个标识符是不是引用自一个对象 | x is y, 类似 id(x) == id(y) , 如果引用的是同一个对象则返回 True,否则返回 False |
is not | is not 是判断两个标识符是不是引用自不同对象 | x is not y , 类似 id(a) != id(b)。如果引用的不是同一个对象则返回结果 True,否则返回 False。 |
注: id() 函数用于获取对象内存地址。
判断两个变量是否相等 is的本质就是通过id函数判断地址是否相同
**is 与 == 区别:**is 用于判断两个变量引用对象是否为同一个, == 用于判断引用变量的值是否相等。
a=1000
b=800
print(id(a))
print(id(b))
c=1000
print(a is b)
print(c is a)#在文件式编程时是True,交互式时False
e=1
f=1
e is f#True
小整数对象池;CPython中整数-5至256,永远存在小整数对象池,不会被释放并可重复使用 ,在文件式Python中优化更好,也有池,比小整数更大,池可以提高内存利用率,无变量引用时,池内的对象不会被释放
Python运算符优先级
以下表格列出了从最高到最低优先级的所有运算符:
运算符 | 描述 |
---|---|
** | 指数 (最高优先级) |
~ + - | 按位翻转, 一元加号和减号 (最后两个的方法名为 +@ 和 -@) |
* / % // | 乘,除,取模和取整除 |
+ - | 加法减法 |
>> << | 右移,左移运算符 |
& | 位 ‘AND’ |
^ | | 位运算符 |
<= < > >= | 比较运算符 |
<> == != | 等于运算符 |
= %= /= //= -= += *= **= | 赋值运算符 |
is is not | 身份运算符 |
in not in | 成员运算符 |
not and or | 逻辑运算符 |
Del语句
删除变量,并解除与对象的关联,如果可能就释放对象,
自动化内存管理的引用计数:
每个对象记录被绑定(引用)的数量,当为0时自动销毁
print输出
printm默认输出是换行的,如果要实现不换行需要在变量末尾加上`end=" 引号里的内容就是间隔的内容"
x="a"
y="b"
# 换行输出
print( x )
print( y )
print('---------')
# 不换行输出
print( x, end=" " )
print( y, end=" " )
print()
"""
a
b
---------
a b
"""
print里放变量,如果用逗号隔开,输出时变量与变量间会自动添加一个空格,字符串用+链接的话就没有空格
num=int(input("请输入一个整数:"))
count=0
while count<num:
if count==0 or count==num-1:
print('*'*num)
else:
print('*'+' '*(num-2)+'*') 逗号隔开: print('*',' '*(num-2),'*')
count+=1
'''
请输入一个整数:6
******
* *
* *
* *
* *
******
'''
逗号隔开: print('*',' '*(num-2),'*')
请输入一个整数:4
****
* *
* *
****
语句行
1.物理行:程序员编写代码的行
2.逻辑行:python解释器需要执行的指令
3.建议一个逻辑行在一个物理行上
4.如果一个物理行中有多个逻辑行需要用分号隔开同一行显示多条语句
Python 可以在同一行中使用多条语句,语句之间使用分号 ; 分割,以下是一个简单的实例:
import sys; x = 'runoob'; sys.stdout.write(x + '\n')
5.如果逻辑行过长,可以使用隐式换行或者显示换行
多行语句
Python 通常是一行写完一条语句,但如果语句很长,我们可以使用反斜杠 \来实现多行语句,例如:
total = item_one + \
item_two + \
item_three
在 [], {}, 或 () 中的多行语句,不需要使用反斜杠 \,例如:
total = ['item_one', 'item_two', 'item_three',
'item_four', 'item_five']
多个语句构成代码组
缩进相同的一组语句构成一个代码块,我们称之代码组。
像if、while、def和class这样的复合语句,首行以关键字开始,以冒号( : )结束,该行之后的一行或多行代码构成代码组。
我们将首行及后面的代码组称为一个子句(clause)。
if expression :
suite
elif expression :
suite
else :
suite
调试Debug
调试:让程序中断,逐语句执行,点击左边物理行的数字,出现红点也就是断点,可以让程序执行到这个代码行终止
目的:审查程序运行时变量取值
:审查程序运行的流程
:调试时拍错的手段
步骤:
1.加断点
2.调试运行
3.执行一行 F8
4.停止调试Ctr+f2
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zfwnvWOC-1630144173744)(C:\Users\13664\AppData\Roaming\Typora\typora-user-images\image-20210808182711465.png)]
条件表达式
有选择的为变量赋值
sex=None
if input("输入性别:")=="男"
sex=1
else:
sex=0
print(sex)
sex=1 if input("请输入性别:")=="男"else 0#不用写sex=0
print(sex)
循环语句
while循环
语法
while 循环条件 :
break#跳出循环
while 循环使用 else 语句
如果 while 后面的条件语句为 false 时,则执行 else 的语句块。
语法格式如下:
while <expr>:
<statement(s)>
else:
<additional_statement(s)>
expr 条件语句为 true 则执行 statement(s) 语句块,如果为 false,则执行 additional_statement(s)。
CTRL+C终止无限循环
TAB键向右缩进,shift+TAB向左缩进
while 计数 再循环体外设置计数变量 count再循环体内进行循环计数
while循环:适合根据条件循环执行
for循环
语法:
#for 变量 in 可迭代对象:
# 循环体
整数生成器:range函数
用于生成一系列可迭代的整数对象
range(开始值(默认为0),结束值,间隔(默认为1)),返回不包括整数值
for+range:更善于执行预定次数
for item in range(5):
print(item)
0
'''
0
1
2
3
4
'''
range也可以倒序
for item in range(100,37,-1):
print(item)
sum+=item
print(sum)
for也可以跟else
num=int(input("请输入一个整数:"))
for it in range(2,num):
if num%it==0:
print(f"{num}不是素数")
break
else:
print(f"{num}是素数")
跳转语句
while 中使用 break:
n = 5
while n > 0:
n -= 1
if n == 2:
break
print(n)
print('循环结束。')
输出结果为:
4
3
循环结束。
while 中使用 continue:
n = 5
while n > 0:
n -= 1
if n == 2:
continue
print(n)
print('循环结束。')
输出结果为:
4
3
1
0
循环结束。
更多实例如下:
实例
for letter in 'Runoob': # 第一个实例
if letter == 'b':
break
print ('当前字母为 :', letter)
var = 10 # 第二个实例
while var > 0:
print ('当期变量值为 :', var)
var = var -1
if var == 5:
break
print ("Good bye!")
执行以上脚本输出结果为:
当前字母为 : R
当前字母为 : u
当前字母为 : n
当前字母为 : o
当前字母为 : o
当期变量值为 : 10
当期变量值为 : 9
当期变量值为 : 8
当期变量值为 : 7
当期变量值为 : 6
Good bye!
以下实例循环字符串 Runoob,碰到字母 o 跳过输出:
实例1
#!/usr/bin/python3 for letter in ‘Runoob’: # 第一个实例 if letter == ‘o’: # 字母为 o 时跳过输出 continue print (‘当前字母 :’, letter) var = 10 # 第二个实例 while var > 0: var = var -1 if var == 5: # 变量为 5 时跳过输出 continue print (‘当前变量值 :’, var) print (“Good bye!”)
执行以上脚本输出结果为:
当前字母 : R
当前字母 : u
当前字母 : n
当前字母 : b
当前变量值 : 9
当前变量值 : 8
当前变量值 : 7
当前变量值 : 6
当前变量值 : 4
当前变量值 : 3
当前变量值 : 2
当前变量值 : 1
当前变量值 : 0
Good bye!
循环语句可以有 else 子句,它在穷尽列表(以for循环)或条件变为 false (以while循环)导致循环终止时被执行,但循环被 break 终止时不执行。
如下实例用于查询质数的循环例子:
实例2
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print(n, '等于', x, '*', n//x)
break
else:
# 循环中没有找到元素
print(n, ' 是质数')
执行以上脚本输出结果为:
2 是质数
3 是质数
4 等于 2 * 2
5 是质数
6 等于 2 * 3
7 是质数
8 等于 2 * 4
9 等于 3 * 3
pass 语句
Python pass是空语句,是为了保持程序结构的完整性。
pass 不做任何事情,一般用做占位语句,如下实例
for letter in 'Runoob':
if letter == 'o':
pass
print ('执行 pass 块')
print ('当前字母 :', letter)
print ("Good bye!")
当前字母 : R
当前字母 : u
当前字母 : n
执行 pass 块
当前字母 : o
执行 pass 块
当前字母 : o
当前字母 : b
Good bye!
容器类型
容器通用操作
切片
Python 不支持单字符类型,单字符在 Python 中也是作为一个字符串使用。
Python 访问子字符串,可以使用方括号 [] 来截取字符串,字符串的截取的语法格式如下:
变量[头下标:尾下标:步长]
message='我是齐天大圣孙悟空'
print(message[0])
print(message[-1])
<<<我
<<<空
#切片
print(message[0:3])
<<<我是齐
#开始值默认为开头
#结束值默认为结尾
print(message[:])
print(message[1:])
print(message[0:len(message)])
'''
我是齐天大圣孙悟空
是齐天大圣孙悟空
我是齐天大圣孙悟空
'''
#逆序
print(message[-1:-5:-1])
print(message[-1:0:-1])
print(message[0:-1])
print(message[::-1])
print(message[::-2])
'''空悟孙圣
空悟孙圣大天齐是
我是齐天大圣孙悟
空悟孙圣大天齐是我
空孙大齐我
'''
#完整输出方式
print(message)
print(message[:])
'''我是齐天大圣孙悟空
我是齐天大圣孙悟空'''
注意:索引不能越界,会报错,但切片越界不报错,但不会输入任何东西
算数运算符
你可以截取字符串的一部分并与其他字段拼接,如下实例:
#!/usr/bin/python3 var1 = ‘Hello World!’ print ("已更新字符串 : ", var1[:6] + ‘Runoob!’)
以上实例执行结果
已更新字符串 : Hello Runoob!
+ | 字符串连接 | a + b 输出结果: HelloPython |
---|---|---|
* | 重复输出字符串 | a*2 输出结果:HelloHello |
[] | 通过索引获取字符串中字符 | a[1] 输出结果 e |
[ : ] | 截取字符串中的一部分,遵循左闭右开原则,str[0:2] 是不包含第 3 个字符的。 | a[1:4] 输出结果 ell |
in | 成员运算符 - 如果字符串中包含给定的字符返回 True | ’H’ in a 输出结果 True |
not in | 成员运算符 - 如果字符串中不包含给定的字符返回 True | ’M’ not in a 输出结果 True |
r/R | 原始字符串 - 原始字符串:所有的字符串都是直接按照字面的意思来使用,没有转义特殊或不能打印的字符。 原始字符串除在字符串的第一个引号前加上字母 r(可以大小写)以外,与普通字符串有着几乎完全相同的语法。 | print( r'\n' ) print( R'\n' ) |
内建函数
字符串str
定义
由一系列字符组成的不可变容器序列,存储的字符的编码值
编码
1.字节byte:计算机最小存储单位,等于8bit
2.字符:单个数字,文字与符号
3.字符集(码表)存储字符与二进制序列的对应关系
4.编码:将字符转换为对应的二进制序列的过程
5.解码::将二进制序列转换为对应字符的过程
6.编码方式:
--ASCII编码:包括英文大小写,数字0-9,特殊字符等字符,每个字符一个字节
--GBK(国标码)编码:兼容ASCII编码,包括21003个中文;英文一个字节,中文2个字节
--Unicode:国际统一编码,旧字符集每个字符2个字节,新字符4个字节,Unicode是一种字符集
--UTF-8编码:Unicode的存储与传输方式,英文一个字节,中文3个字节
Unicode 字符串
在Python2中,普通字符串是以8位ASCII码进行存储的,而Unicode字符串则存储为16位unicode字符串,这样能够表示更多的字符集。使用的语法是在字符串前面加上前缀 u。
在Python3中,所有的字符串都是Unicode字符串。
字符串编码相关函数
ord(字符串):返回该字符串的Unicode编码
chr(数字):返回该数字对应的字符串
字符串引号
字符串有单引号’’,双引号“”,和三引号‘’‘ ’‘’,“”“ ”“”“
单引号里可以包含双引号,双引号里可以包含单引号,
三引号所见即所得,可包含单引号与双引号
py#单引号内的双引号不算结束符,可以输出
message='单引号里的"双引号"'
print(message)
message02="双引号里的'单引号'"
print(message2)
message3="""
ass
aas ddd
s aa"""
print(message3)
输出:
单引号里的"双引号"
双引号里的'单引号'
ass
aas ddd
s aa
字符串格式化
Python 支持格式化字符串的输出 。尽管这样可能会用到非常复杂的表达式,但最基本的用法是将一个值插入到一个有字符串格式符 %s 的字符串中。
在 Python 中,字符串格式化使用与 C 中 sprintf 函数一样的语法。
print ("我叫 %s 今年 %d 岁!" % ('小明', 10))
以上实例输出结果:
我叫 小明 今年 10 岁!
符 号 | 描述 |
---|---|
%c | 格式化字符及其ASCII码 |
%s | 格式化字符串 |
%d | 格式化整数 |
%u | 格式化无符号整型 |
%o | 格式化无符号八进制数 |
%x | 格式化无符号十六进制数 |
%X | 格式化无符号十六进制数(大写) |
%f | 格式化浮点数字,可指定小数点后的精度 |
%e | 用科学计数法格式化浮点数 |
%E | 作用同%e,用科学计数法格式化浮点数 |
%g | %f和%e的简写 |
%G | %f 和 %E 的简写 |
%p | 用十六进制数格式化变量的地址 |
Python 的字符串内建函数
Python 的字符串常用内建函数如下:
序号 | 方法及描述 |
---|---|
1 | capitalize() 将字符串的第一个字符转换为大写 |
2 | center(width, fillchar) 返回一个指定的宽度 width 居中的字符串,fillchar 为填充的字符,默认为空格。 |
3 | count(str, beg= 0,end=len(string)) 返回 str 在 string 里面出现的次数,如果 beg 或者 end 指定则返回指定范围内 str 出现的次数 |
4 | bytes.decode(encoding=“utf-8”, errors=“strict”) Python3 中没有 decode 方法,但我们可以使用 bytes 对象的 decode() 方法来解码给定的 bytes 对象,这个 bytes 对象可以由 str.encode() 来编码返回。 |
5 | encode(encoding=‘UTF-8’,errors=‘strict’) 以 encoding 指定的编码格式编码字符串,如果出错默认报一个ValueError 的异常,除非 errors 指定的是’ignore’或者’replace’ |
6 | endswith(suffix, beg=0, end=len(string)) 检查字符串是否以 obj 结束,如果beg 或者 end 指定则检查指定的范围内是否以 obj 结束,如果是,返回 True,否则返回 False. |
7 | expandtabs(tabsize=8) 把字符串 string 中的 tab 符号转为空格,tab 符号默认的空格数是 8 。 |
8 | find(str, beg=0, end=len(string)) 检测 str 是否包含在字符串中,如果指定范围 beg 和 end ,则检查是否包含在指定范围内,如果包含返回开始的索引值,否则返回-1 |
9 | index(str, beg=0, end=len(string)) 跟find()方法一样,只不过如果str不在字符串中会报一个异常。 |
10 | isalnum() 如果字符串至少有一个字符并且所有字符都是字母或数字则返 回 True,否则返回 False |
11 | isalpha() 如果字符串至少有一个字符并且所有字符都是字母或中文字则返回 True, 否则返回 False |
12 | isdigit() 如果字符串只包含数字则返回 True 否则返回 False… |
13 | islower() 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是小写,则返回 True,否则返回 False |
14 | isnumeric() 如果字符串中只包含数字字符,则返回 True,否则返回 False |
15 | isspace() 如果字符串中只包含空白,则返回 True,否则返回 False. |
16 | istitle() 如果字符串是标题化的(见 title())则返回 True,否则返回 False |
17 | isupper() 如果字符串中包含至少一个区分大小写的字符,并且所有这些(区分大小写的)字符都是大写,则返回 True,否则返回 False |
18 | join(seq) 以指定字符串作为分隔符,将 seq 中所有的元素(的字符串表示)合并为一个新的字符串 |
19 | len(string) 返回字符串长度 |
20 | [ljust(width, fillchar]) 返回一个原字符串左对齐,并使用 fillchar 填充至长度 width 的新字符串,fillchar 默认为空格。 |
21 | lower() 转换字符串中所有大写字符为小写. |
22 | lstrip() 截掉字符串左边的空格或指定字符。 |
23 | maketrans() 创建字符映射的转换表,对于接受两个参数的最简单的调用方式,第一个参数是字符串,表示需要转换的字符,第二个参数也是字符串表示转换的目标。 |
24 | max(str) 返回字符串 str 中最大的字母。 |
25 | min(str) 返回字符串 str 中最小的字母。 |
26 | [replace(old, new , max]) 把 将字符串中的 old 替换成 new,如果 max 指定,则替换不超过 max 次。 |
27 | rfind(str, beg=0,end=len(string)) 类似于 find()函数,不过是从右边开始查找. |
28 | rindex( str, beg=0, end=len(string)) 类似于 index(),不过是从右边开始. |
29 | [rjust(width,, fillchar]) 返回一个原字符串右对齐,并使用fillchar(默认空格)填充至长度 width 的新字符串 |
30 | rstrip() 删除字符串末尾的空格或指定字符。 |
31 | split(str="", num=string.count(str)) 以 str 为分隔符截取字符串,如果 num 有指定值,则仅截取 num+1 个子字符串 |
32 | [splitlines(keepends]) 按照行(’\r’, ‘\r\n’, \n’)分隔,返回一个包含各行作为元素的列表,如果参数 keepends 为 False,不包含换行符,如果为 True,则保留换行符。 |
33 | startswith(substr, beg=0,end=len(string)) 检查字符串是否是以指定子字符串 substr 开头,是则返回 True,否则返回 False。如果beg 和 end 指定值,则在指定范围内检查。 |
34 | [strip(chars]) 在字符串上执行 lstrip()和 rstrip() |
35 | swapcase() 将字符串中大写转换为小写,小写转换为大写 |
36 | title() 返回"标题化"的字符串,就是说所有单词都是以大写开始,其余字母均为小写(见 istitle()) |
37 | translate(table, deletechars="") 根据 str 给出的表(包含 256 个字符)转换 string 的字符, 要过滤掉的字符放到 deletechars 参数中 |
38 | upper() 转换字符串中的小写字母为大写 |
39 | zfill (width) 返回长度为 width 的字符串,原字符串右对齐,前面填充0 |
40 | isdecimal() 检查字符串是否只包含十进制字符,如果是返回 true,否则返回 false。 |
列表list
定义
由一系列变量组成的可变序列容器 存储变量
与字符串比较:由一系列字符组成的不可变序列容器 存储编码值
序列是 Python 中最基本的数据结构。
序列中的每个值都有对应的位置值,称之为索引,第一个索引是 0,第二个索引是 1,依此类推。
Python 有 6 个序列的内置类型,但最常见的是列表和元组。
列表都可以进行的操作包括索引,切片,加,乘,检查成员。
此外,Python 已经内置确定序列的长度以及确定最大和最小的元素的方法。
列表是最常用的 Python 数据类型,它可以作为一个方括号内的逗号分隔值出现。
列表的数据项不需要具有相同的类型
**创建一个列表,**只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示:
list1 = ['Google', 'Runoob', 1997, 2000]
list2 = [1, 2, 3, 4, 5 ]
list3 = ["a", "b", "c", "d"]
list4 = ['red', 'green', 'blue', 'yellow', 'white', 'black']
创建空列表
list01=[]
list01=list(容器) 将另外一种容器变成列表
列表里存储的是变量,然后变量存的是元素对象的地址
'''计算最小值不(使用min)'''
list01=[23,4,6,132,5123,52]
min_num=list01[0]#是list01[0]这个变量存储的地址赋值给min_num
for item in range(1,len(list01)):
if min_num>list01[item]:
min_num=list01[item]
print(min_num)
切片就会创建新的列表,
索引是把列表里的东西拿出来
列表的增删查改
1.增加
追加内容:列表名.append(元素)
插入内容:列表名.insert(索引位置,元素)
2.删除
del 列表名[索引/切片]
列表名.remove(变量)
删除一般是后一个替换前一个,如果从前往后会有循环删除就会遗漏,从后往前删就不会有遗漏
list01=[54,25,12,42,35,17]
for item in list01:
if item>30:
list01.remove(item)
print(list01)#[25, 12, 35, 17]
#35没删除是因为remove函数35替换了42,下一次循环直接从17开始略过了35
从后往前删除
list01=[54,25,12,42,35,17]
for item in range(len(list01)-1,-1,-1):
if list01[item]>30:
list01.remove(list01[item])
print(list01)#[25, 12, 17]
3.查找(索引)切片
#从列表中获取一片元素组成新列表
变量=列表名[切片]
列表名[切片]=变量
判断变量是否在列表里 运用成员运算符 变量 in 列表 变量 not in 列表
'''双色球'''
import random
red_ball=[]
blue_ball=random.randint(1,17)
while len(red_ball)<6:
item=random.randint(1,33)
if item not in red_ball:
red_ball.append(item)
print(red_ball)
print(blue_ball)
while True:
r_num01=int(input("请输入第1个红球号码:"))
r_num02=int(input("请输入第2个红球号码:"))
if r_num01<1 or r_num01>33 or r_num02<1 or r_num02>33:
print('号码不在范围内')
continue
elif r_num01==r_num02:
print('号码已经重复')
continue
else:
break
b_num=int(input("请输入篮球号码:"))
if b_num>17 or b_num<1:
print('号码不在范围内')
if r_num01 in red_ball and r_num02 in red_ball and b_num==blue_ball:#判断你选择的号码是否在随机列表里
print('恭喜你中奖了!')
else:
print('很抱歉,您未中奖!')
import random
list_ball=[]
while len(list_ball)<6:
item=random.randint(1,33)
if item not in list_ball:
list_ball.append(item)
list_ball.append(random.randint(1, 17))
print(list_ball)
list02=[]
while len(list02)<6:
r_num=int(input("请输入第%d个红球号码:"%(len(list02)+1)))
if r_num>33 or r_num<1:
print('号码不在范围内')
continue
elif r_num in list02:
print('号码已经重复')
continue
else:
list02.append(r_num)
while len(list02)<7:
b_num=int(input("请输入蓝球号码:"))
if b_num>17 or b_num<1:
print('号码不在范围内')
else:
list02.append(b_num)
if list_ball==list02:
print('恭喜你中奖了!')
else:
print('很抱歉,您未中奖!')
4.遍历所有元素
正序
list01=[1,2,3,4,5]
for item in list01:
print(item)
倒序
list01=[1,2,3,4,5]
for item in range(len(list01)-1,-1,-1):#正数索引
print(list01[item])
list01=[1,2,3,4,5]
for item in range(-1,-len(list01)-1,-1):#负数索引
print(list01[item])
浅拷贝
在复制过程中,只会复制一层变量,不会复制深层变量绑定的对象copy函数
list01=[100,[200,300]]
#list02=list01[:]
list02=list01.copy()
list01[0]=400
list01[1][0]=500
print(list02[0])#100
print(list02[1][0])#500
深拷贝
复制整个依赖的对象
import copy
deepcopy()
import copy
list01=[100,[200,300]]
list02=list01[:]
list02=list01.copy()
list01[0]=400
list01[1][0]=500
print(list01)#[400, [500, 300]]
print(list02)#[100, [500, 300]]
list02=copy.deepcopy(list01)
list01[1][0]=500
print(list01)#[400, [500, 300]]
print(list02)#[400, [500, 300]]
列表推导式
定义:使用简单方法,将可迭代对象转换为列表
语法:变量=[表达式 for 变量 in 可迭代对象]
变量=[表达式 for 变量 in 可迭代对象 if 条件]
#使用range生成1--10之间的数字,将数字的平方存入list01中
list01=[item**2 for item in range(1,11)]
print(list01)#[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
#将list01中所有奇数存入list02
list02=[item for item in list01 if item%2!=0]
print(list02)#[1, 9, 25, 49, 81]
#将list01中所有偶数存入list03
list03=[item for item in list01 if item%2==0]
print(list03)#[4, 16, 36, 64, 100]
#将list01中所有大于5的偶数加1存入list04
list04=[item+1 for item in list01 if item>5 and item%2==0]
print(list04)#[17, 37, 65, 101]
元组tuple
定义
1.由一系列变量组成的不可变序列容器
2.不可变指的是一旦创建一个元组,不可以再添加/删除/修改元素
Python 的元组与列表类似,不同之处在于元组的元素不能修改。
元组使用小括号 ( ),列表使用方括号 [ ]。
元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可。
>>> tup1 = (‘Google’, ‘Runoob’, 1997, 2000)
>>> tup2 = (1, 2, 3, 4, 5 )
>>> tup3 = “a”, “b”, “c”, “d” # 不需要括号也可以
>>> type(tup3)
<class ‘tuple’>
创建空元组
tup1 = ()
元组中只包含一个元素时,需要在元素后面添加逗号 , ,否则括号会被当作运算符使用:
>>> tup1 = (50)
>>> type(tup1) # 不加逗号,类型为整型
<class ‘int’>
>>> tup1 = (50,)
>>> type(tup1) # 加上逗号,类型为元组
<class ‘tuple’>
元组与字符串类似,下标索引从 0 开始,可以进行截取,组合等。
应用
变量交换的本质就是元祖x,y=4,5
本质是x,y=(4,5)
格式化字符串的本质也是创建元祖:"行吗:%s",年龄:%d%('李博宇'19)
虽然元组不能更改变量但是可以更改变量所指向地址的里的内容,但变量地址不改变
t1=(1,2,3,[4,5,6])
print(id(t1[3]))#1730093208072
print(t1[3][1])#5
t1[3][1]=11
print(t1[3][1])#11
print(id(t1[3]))#1730093208072 地址未变
元组所指向的内存实际上保存的是元组内数据的内存地址集合(即 t[0], t[1]…t[n] 的内存地址),且元组一旦建立,这个集合就不能增加修改删除,一旦集合内的地址发生改变,必须重新分配元组空间保存新的地址集(元组类似 C 语言里的指针数组,只不过这个数组不能被修改)。
测试下面代码:
print("连接前:")
t1=(1,2,"3")
t2=("4",5,["d1","d2"])
print("t1=",t1)
print("t2=",t2)
print("t1:",id(t1))
print("t2:",id(t2))
print("t1[0]:",id(t1[0]))
print("t1[1]:",id(t1[1]))
print("t1[2]:",id(t1[2]))
print("t2[0]:",id(t2[0]))
print("t2[1]:",id(t2[1]))
print("t2[2]:",id(t2[2]))
print("连接后:")
t1= t1+t2
print("t1(t1+t2):",id(t1))
print("t1[0]:",id(t1[0]))
print("t1[1]:",id(t1[1]))
print("t1[2]:",id(t1[2]))
print("t1[3]:",id(t1[3]))
print("t1[4]:",id(t1[4]))
print("t1[5]:",id(t1[5]))
t1[5].append("d3")
print("t1[5]增加d3:")
print("t1[5]=",t1[5])
print("t1[5]:",id(t1[5]))
print("t2=",t2)
输出:
连接前:
t1= (1, 2, '3')
t2= ('4', 5, ['d1', 'd2'])
t1: 1719219799168
t2: 1719219799528
t1[0]: 1378249760
t1[1]: 1378249792
t1[2]: 1719200188208
t2[0]: 1719199042336
t2[1]: 1378249888
t2[2]: 1719219441608
连接后:
t1(t1+t2): 1719222365256
t1[0]: 1378249760
t1[1]: 1378249792
t1[2]: 1719200188208
t1[3]: 1719199042336
t1[4]: 1378249888
t1[5]: 1719219441608
t1[5]增加d3:
t1[5]= ['d1', 'd2', 'd3']
t1[5]: 1719219441608
t2= ('4', 5, ['d1', 'd2', 'd3'])
实例
输入日期(年月日),打印是这一年的第几天
year=int(input('请输入年份:'))
month=int(input('请输入月份'))
day=int(input('请输入日:'))
sum_day=0
tuple_m=(31,28,31,30,31,30,31,31,30,31,30,31)
# #索引方法
# for value in range(month-1):
# sum_day+=tuple_m[value]
#切片
sum_day=sum(tuple_m[:month-1])
if (year%4==0 and year%100!=0 or year%400==0) and month>2:
sum_day+=1
sum_day+=day
print(f'这是{year}年的第{sum_day}天')
字典
定义
1.由一系列键值对组成的可变映射容器
2.映射:一一对应的关系,且每条记录无序(根据哈希算法)
3.键是唯一且不可变的(字符串/数字/元祖),值没有限制
说明
字典是另一种可变容器模型,且可存储任意类型对象。
字典的每个键值 key=>value 对用冒号 : 分割,每个对之间用逗号(,)分割,整个字典包括在花括号 {} 中 ,格式如下所示:
d = {key1 : value1, key2 : value2, key3 : value3 }
键必须是唯一的,但值则不必。
值可以取任何数据类型,但键必须是不可变的,如字符串,数字。
一个简单的字典实例:
dict = {'name': 'runoob', 'likes': 123, 'url': 'www.runoob.com'}
创建字典
#空列表
dict01={}
dict02=dict(('这是','容器'))
#默认值
dict01 = {'name': 'runoob', 'likes': 123, 'url': 'www'}#{'name': 'runoob', 'likes': 123, 'url': 'www'}
list01=['a','b','aa','ss']
list01=[('a','b'),('aa','ss')]#将列表改为字典,需要把四个元素变为两个元组,成为键值对
dict02=dict(list01)
print(dict02)#{'a': 'b', 'aa': 'ss'}
增删查改
删除 del 字典名[‘键’]
改 字典名[键]=更改值
遍历字典
#遍历列表
dict01={'a':1,'b':2,'c':3,'d':4}
for key in dict01:#得到的是键
#或者for key in dict01.keys():
print(key,':',dict01[key])
for value in dict01.values():#得到的是值
print(value)
for item in dict01.items():#得到键值对(元组形式)
print(item)
for k,v in dict01.items():#分别存储键值
print(k,v)
实例1
#录入商品信息,名称和单价,然后一一打印,sh
dict_thing={}
while True:
name=input('请输入商品名称:')
if name=='':
break
price=input('请输入商品单价:')
dict_thing[name]=price
for k,v in dict_thing.items():
print(f'{k}的单价为{v}每斤')
请输入商品名称:黄瓜
请输入商品单价10
请输入商品名称:土豆
请输入商品单价2
请输入商品名称:
黄瓜的单价为10
土豆的单价为2
实例2
描述学生信息
#字典内嵌列表
list_student_info={}
dict_student=[]
while True:
name=input('请输入学生姓名:')
if name=='':
break
age=input('请输入年龄:')
sex=input('请输入性别:')
grade=input('请输入成绩:')
dict_student =[age, sex, grade]
list_student_info[name]=dict_student
#如果需要居中输出在宽度前面加一个^
mat = "{:20}\t{:20}\t{:20}"
print(mat.format('姓名','年龄','性别','成绩'))
for k,v in list_student_info.items():
print(mat.format(k,v[0],v[1],v[2]))
#列表内嵌字典
list_student_info=[]
dict_student={}
while True:
name=input('请输入学生姓名:')
if name=='':
break
age=input('请输入年龄:')
sex=input('请输入性别:')
grade=input('请输入成绩:')
dict_student ={'name':name,'age':age,'sex': sex,'grade': grade}
list_student_info.append(dict_student)
#如果需要居中输出在宽度前面加一个^
mat = "{:20}\t{:20}\t{:20}\t{:20}"
print(mat.format('姓名','年龄','性别','成绩'))
for dict in list_student_info:
print(mat.format(dict['name'],dict['age'],dict['sex'],dict['grade']))
字典与列表比较
字典:
——优点:根据建获取值,读取速度快
代码可读性高
——缺点:内存占用大
获取值只能根据键,不灵活
列表:
——优点:根据索引/切片获取元素,更灵活,占用内存较小
——缺点:若信息较多,可读性不高
根据实际情况综合运用
字典列表中键值对value的存在判断
1、最基础的:for迭代与if判断的结合
dict_list = [{"name": "小明",
"qq": "123",
"age": "18"},
{"name": "小美",
"qq": "110",
"age": "17"}]
name = input("请输入查找的学生信息:")
for info in dict_list:
if name == info["name"]:
print("存在该学生")
break
else:
print("该学生不存在")
2、运用dict.values()方法返回字典中所有值value来进行判断:
if name in info.values()
字典推导式
字典可以通过以下方法调换 key和 value,当然要注意原始 value 的类型,必须是不可变类型:
dic = {
'a': 1,
'b': 2,
'c': 3,
}
reverse = {v: k for k, v in dic.items()}#字典推导式
print(dic)
print(reverse)
输出如下:
{'a': 1, 'b': 2, 'c': 3}
{1: 'a', 2: 'b', 3: 'c'}
list01=['ads','sd','sssa']
list02=[101,101,103]
dic={list01[i]:list02[i] for i in range(3)}
print(dic)
#互换键和值但不会合并相同的值,需要把字典变成列表
list03=[(v,k) for k,v in dic.items()]
print(list03)
#变成字典后重复的会合并保留最后一次更改的值
dic={v:k for k,v in dic.items()}
print(dic)
输出如下:
{'ads': 101, 'sd': 101, 'sssa': 103}
{101: 'sd', 103: 'sssa'}#key重复,更新为最后一次101
集合
定义
基础操作
#创建集合
set01={'a','b','c'}#必须带有默认值,若为空则视为字典
set02=set()#创建空集合
set02=set('anbcsdc')#利用set函数创建集合,把可迭代对象转化为集合,合并相同的值
#2.添加元素
set02.add('qtx')
#3.删除元素
set02.remove('a')
# 4.遍历元素
for item in set02:
print(item)
# 5.数学运算
#交集
set01={1,2,3}
set02={2,3,4}
print(set01&set02)#{2, 3}
#并集
print(set01|set02)#{1, 2, 3, 4}
#补集
print(set01^set02)#{1, 4}
#子集
set03={1,2}
print(set03<set01)#True
print(set03<set03)#False
print(set03<=set03)#True
#超集
print(set01>set03)#True
#差集(属于set01不属于set02)
print(set01-set02)#{1}
固定集合frozenset
定义:不可变集合
作用
固定集合可以作为字典的键,还可以作为字典的值
创建固定集合
frozenset(可迭代对象)
set01=frozenset([1,2,3,4,5])
print(set01)#frozenset({1, 2, 3, 4, 5})
双for循环
#外层循环控制行
for r in range(6):
#内层循环控制列
for c in range(3):
print('*',end=' ')
print('#',end=' ')
print()
for r in range(4):
for c in range(r+1):
print('*',end=' ')
print()
#排序
list01=[97,42,1,21,3,46,84,32]
for r in range(len(list01)-1):#提出要比较的第一个元素到倒数第二元素
for c in range(r+1,len(list01)):#将第r个元素与r+1后面的元素一一比较
if list01[r]>list01[c]:
list01[r],list01[c]=list01[c],list01[r]
print(list01)
函数
写在前面:函数讲究分而治之,一个函数实现一个功能,不要将一个函数包含多种功能,利用函数嵌套函数,封装功能,选中一个一段代码ctrl+alt+m,直接生成一个函数
def get_prime(begin,end):
"""
判断begin到end(包括)之间的数是否为素数
:param begin:
:param end:
:return:
"""
list01=[]
for number in range(begin,end+1):
for item in range(2,number):
if number%item==0:
break
# if item==number-1:
# list01.append(number)
else:
list01.append(number)
return list01
print(get_prime(2,100))
#editon2
def is_prime(number):
for item in range(2, number):
if number % item == 0:
return False
else:
return True
def get_prime(begin,end):
"""
判断begin到end(包括)之间的数是否为素数
:param begin:
:param end:
:return:所有素数的列表
"""
list01=[]
#生产范围内的整数
for number in range(begin,end+1):
if is_prime(number):
list01.append(number)
return list01
print(get_prime(2,100))
#改进
def get_prime(begin,end):
"""
判断begin到end(包括)之间的数是否为素数
:param begin:
:param end:
:return:所有素数的列表
"""
return [number for number in range(begin,end+1) if is_prime(number)]
print(get_prime(2,100))
语法
Python 定义函数使用 def 关键字,一般格式如下:
def 函数名(参数列表):
函数体
定义一个函数
你可以定义一个由自己想要功能的函数,以下是简单的规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号 : 起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。
注:1.函数名非常重要,一定要体现函数功能,一般用动词表示
2.第一行一定要写注释 打出三个引号然后回车会出现下面的注释
'''
#描述方法
:param number: #参数说明
:return: #返回值说明
'''
函数可以嵌套
def is_leapYear(year):
if year%4==0 and year%100!=0 or year%400==0:
return True
else:
return False
def get_day_by_month(year,month):
if month<1 or month>12:
return -1
if month==2:
# if is_leapYear(year):
# return 29
# else:
# return 28
return 29 if is_leapYear(year) else 28#if条件表达式
if month in(4,6,9,11):
return 30
return 31
print(get_day_by_month(2000,2))
参数传递
在 python 中,类型属于对象,变量是没有类型的:
a=[1,2,3]
a="Runoob"
以上代码中,[1,2,3] 是 List 类型,“Runoob” 是 String 类型,而变量 a 是没有类型,她仅仅是一个对象的引用(一个指针),可以是指向 List 类型对象,也可以是指向 String 类型对象。
可更改(mutable)与不可更改(immutable)对象
在 python 中,strings, tuples, 和 numbers 是不可更改的对象,而 list,dict 等则是可以修改的对象。
- **不可变类型:**变量赋值 a=5 后再赋值 a=10,这里实际是新生成一个 int 值对象 10,再让 a 指向它,而 5 被丢弃,不是改变 a 的值,相当于新生成了 a。
- **可变类型:**变量赋值 la=[1,2,3,4] 后再赋值 la[2]=5 则是将 list la 的第三个元素值更改,本身la没有动,只是其内部的一部分值被修改了。
python 函数的参数传递:
- **不可变类型:**类似 C++ 的值传递,如整数、字符串、元组。如 fun(a),传递的只是 a 的值,没有影响 a 对象本身。如果在 fun(a) 内部修改 a 的值,则是新生成一个 a 的对象。
- **可变类型:**类似 C++ 的引用传递,如 列表,字典。如 fun(la),则是将 la 真正的传过去,修改后 fun 外部的 la 也会受影响
python 中一切都是对象,严格意义我们不能说值传递还是引用传递,我们应该说传不可变对象和传可变对象。
python 传不可变对象实例
通过 id() 函数来查看内存地址变化:
实例(Python 3.0+)
def change(a):
print(id(a)) # 指向的是同一个对象
a=10
print(id(a)) # 一个新对象
a=1
print(id(a))
change(a)
以上实例输出结果为:
4379369136
4379369136
4379369424
可以看见在调用函数前后,形参和实参指向的是同一个对象(对象 id 相同),在函数内部修改形参后,形参指向的是不同的 id。
传可变对象实例
可变对象在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了。例如:
实例(Python 3.0+)
# 可写函数说明
def changeme( mylist ):
"修改传入的列表"
mylist.append([1,2,3,4])
print ("函数内取值: ", mylist)
return
# 调用changeme函数
mylist = [10,20,30]
changeme( mylist )
print ("函数外取值: ", mylist)
传入函数的和在末尾添加新内容的对象用的是同一个引用。故输出结果如下:
函数内取值: [10, 20, 30, [1, 2, 3, 4]]
函数外取值: [10, 20, 30, [1, 2, 3, 4]]
#在方法区中存储函数代码,不执行函数体
def fun01(a):
'''因为调用函数,所以开辟一块内存空间,叫做栈帧
用于存储在函数内部定义的变量(包含参数)
函数执行完毕后,栈帧立即释放(其中函数内部的变量也会被销毁)'''
a=100#改变的是fun01栈帧中变量a的指向
def fun02(a):
a[1]=100#改变的是传入的可变对象
num=1
list01=[1,[2,3]]
fun01(num)
print(num)#1
fun02(list01)
print(list01)#[100]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RT2jZaA3-1630144173752)(file:///D:\消息文档\136648417\Image\C2C\AAC21ED3395ECBFF2738AC2067775AEC.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XAf6izGx-1630144173753)(file:///D:\消息文档\136648417\Image\C2C\9B0E32407A27DD78311760BE25DDDA80.png)]
# 定义列表升序排列函数
list01=[97, 42, 1, 21, 3, 46, 84, 32]
def sort(list_target):
'''
1.传入的是可变对象
2.函数体修改的是传入的对象
满足以上条件,就无需通过返回值传递结果
:param list_target:
:return:
'''
for r in range(len(list_target) - 1):
for c in range(r+1, len(list_target)):
if list_target[r]>list_target[c]:
list_target[r], list_target[c]= list_target[c], list_target[r]
#return list_target
#print(sort(list01))
sort(list01)
print(list01)
作用域LEGB
A scope is a textual region of a Python program where a namespace is directly accessible. “Directly accessible” here means that an unqualified reference to a name attempts to find the name in the namespace.
作用域就是一个 Python 程序可以直接访问命名空间的正文区域。
在一个 python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。
Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python 的作用域一共有4种,分别是:
有四种作用域:
- L(Local):最内层,包含局部变量,比如一个函数/方法内部。
- E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
- G(Global):当前脚本的最外层,比如当前模块的全局变量。
- B(Built-in): 包含了内建的变量/关键字等,最后被搜索。
规则顺序: L –> E –> G –> B。
在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内置中找。
g_count = 0 # 全局作用域
def outer():
o_count = 1 # 闭包函数外的函数中
def inner():
i_count = 2 # 局部作用域
内置作用域是通过一个名为 builtin 的标准模块来实现的,但是这个变量名自身并没有放入内置作用域内,所以必须导入这个文件才能够使用它。在Python3.0中,可以使用以下的代码来查看到底预定义了哪些变量:
>>> import builtins
>>> dir(builtins)
Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问,如下代码:
>>> if True:
... msg = 'I am from Runoob'
...
>>> msg
'I am from Runoob'
>>>
实例中 msg 变量定义在 if 语句块中,但外部还是可以访问的。
如果将 msg 定义在函数中,则它就是局部变量,外部不能访问:
>>> def test():
... msg_inner = 'I am from Runoob'
...
>>> msg_inner
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'msg_inner' is not defined
>>> py
从报错的信息上看,说明了 msg_inner 未定义,无法使用,因为它是局部变量,只有在函数内可以使用。
全局变量和局部变量
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问。调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。如下实例:
实例(Python 3.0+)
total = 0 # 这是一个全局变量
# 可写函数说明
def sum( arg1, arg2 ):
#返回2个参数的和."
total = arg1 + arg2 # total在这里是局部变量.这里的total是新创建的和外部的不一样属于两个变量
print ("函数内是局部变量 : ", total)
return total
#调用sum函数
sum( 10, 20 )
print ("函数外是全局变量 : ", total)
函数内是局部变量 : 30
函数外是全局变量 : 0
global 和 nonlocal关键字
当内部作用域想修改外部作用域的变量时,就要用到 global 和 nonlocal 关键字了。
以下实例修改全局变量 num:
实例(Python 3.0+)
num = 1
def fun1():
global num # 需要使用 global 关键字声明
print(num)
num = 123
print(num)
fun1()
print(num)
以上实例输出结果:
1
123
123
如果要修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要 nonlocal 关键字了,如下实例:
实例(Python 3.0+)
#!/usr/bin/python3
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num)
inner()
print(num)
outer()
以上实例输出结果:
100
100
另外有一种特殊情况,假设下面这段代码被运行:
实例(Python 3.0+)
a = 10
def test():
a = a + 1
print(a)
test()
以上程序
执行,报错信息如下:
Traceback (most recent call last):
File "test.py", line 7, in <module>
test()
File "test.py", line 5, in test
a = a + 1
UnboundLocalError: local variable 'a' referenced before assignment
错误信息为局部作用域引用错误,因为 test 函数中的 a 使用的是局部,未定义,无法修改。
修改 a 为全局变量:
实例
a = 10
def test():
global a
a = a + 1
print(a)
test()
执行输出结果为:
11
也可以通过函数参数传递:
a = 10
def test(a):
a = a + 1
print(a)
test(a)
执行输出结果为:
11
函数参数
以下是调用函数时可使用的正式参数类型:
- 必需参数
- 关键字参数
- 默认参数
- 不定长参数
实际参数
'''函数参数
实参
'''
def fun01(a,b,c,d):
print(a)
print(b)
print(c)
print(d)
#位置实参:实参与形参位置依次对应
fun01(1,2,3,4)
#关键字实参:实参与形参根据名称进行对应
fun01(b=1,a=2,c=4,d=3)
#序列实参:星号将序列拆分后按位置与形参进行对应
# 如果参数很多,可以存储在序列(字符串/列表/元组)中
# 再通过*拆分,直接传入函数
list01=['a','b','c','d']
fun01(*list01)
#字典实参:双星号将字典拆分后按名称与形参进行对应
#如果键与形参不一样那么会报错
dict01={'a':1,'c':3,'d':4,'b':2}
fun01(**dict01)
形式参数
"""
函数参数
形式参数
"""
#1.缺省(默认)参数:如果实参不提供,可以使用默认值,但必须从右到左在后面
def fun01(a=None,b=0,c=0,d=0):
print(a,b,c,d)
#2.关键字实参+缺省形参:调用者可以随意传递参数
fun01(b=2,c=3)#None 2 3 0
#不使用关键字会默认从左到右依次赋值
fun01(2,3)#2 3 0 0
#3.星号元组形参:*将所有实参合并为一个元组
# 一般将星号形参名写成*args,且只能有一个
#作用:可以传递无限个实参
def fun03(a,*args):
print(a,args)
fun03(1,2,3)#1 (2, 3)
#4.命名关键字形参:在星号元组后的位置形参
# 目的:要求实参必须使用关键字实参,否则报错
def fun04(a,*args,b):
print(a,args,b)
fun04(1,2,3,4,b=5)#1 (2, 3, 4) 5
#5.字典形参:实参可以传递数量无限的关键字实参
#目的: 实参可以传递数量无限的关键字实参
# 一般命名为**kwargs
def fun05(**kwargs):
print(kwargs)
fun05(a=1,b=2)#{'a': 1, 'b': 2}
参数从左到右的顺序
位置形参——>星号元组形参——>命名关键字形参——>双星号字典形参
un1()
print(num)
以上实例输出结果:
1
123
123
如果要修改嵌套作用域(enclosing 作用域,外层非全局作用域)中的变量则需要 nonlocal 关键字了,如下实例:
## 实例(Python 3.0+)
```python
#!/usr/bin/python3
def outer():
num = 10
def inner():
nonlocal num # nonlocal关键字声明
num = 100
print(num)
inner()
print(num)
outer()
以上实例输出结果:
100
100
另外有一种特殊情况,假设下面这段代码被运行:
实例(Python 3.0+)
a = 10
def test():
a = a + 1
print(a)
test()
以上程序
执行,报错信息如下:
Traceback (most recent call last):
File "test.py", line 7, in <module>
test()
File "test.py", line 5, in test
a = a + 1
UnboundLocalError: local variable 'a' referenced before assignment
错误信息为局部作用域引用错误,因为 test 函数中的 a 使用的是局部,未定义,无法修改。
修改 a 为全局变量:
实例
a = 10
def test():
global a
a = a + 1
print(a)
test()
执行输出结果为:
11
也可以通过函数参数传递:
a = 10
def test(a):
a = a + 1
print(a)
test(a)
执行输出结果为:
11
函数参数
以下是调用函数时可使用的正式参数类型:
- 必需参数
- 关键字参数
- 默认参数
- 不定长参数
实际参数
'''函数参数
实参
'''
def fun01(a,b,c,d):
print(a)
print(b)
print(c)
print(d)
#位置实参:实参与形参位置依次对应
fun01(1,2,3,4)
#关键字实参:实参与形参根据名称进行对应
fun01(b=1,a=2,c=4,d=3)
#序列实参:星号将序列拆分后按位置与形参进行对应
# 如果参数很多,可以存储在序列(字符串/列表/元组)中
# 再通过*拆分,直接传入函数
list01=['a','b','c','d']
fun01(*list01)
#字典实参:双星号将字典拆分后按名称与形参进行对应
#如果键与形参不一样那么会报错
dict01={'a':1,'c':3,'d':4,'b':2}
fun01(**dict01)
形式参数
"""
函数参数
形式参数
"""
#1.缺省(默认)参数:如果实参不提供,可以使用默认值,但必须从右到左在后面
def fun01(a=None,b=0,c=0,d=0):
print(a,b,c,d)
#2.关键字实参+缺省形参:调用者可以随意传递参数
fun01(b=2,c=3)#None 2 3 0
#不使用关键字会默认从左到右依次赋值
fun01(2,3)#2 3 0 0
#3.星号元组形参:*将所有实参合并为一个元组
# 一般将星号形参名写成*args,且只能有一个
#作用:可以传递无限个实参
def fun03(a,*args):
print(a,args)
fun03(1,2,3)#1 (2, 3)
#4.命名关键字形参:在星号元组后的位置形参
# 目的:要求实参必须使用关键字实参,否则报错
def fun04(a,*args,b):
print(a,args,b)
fun04(1,2,3,4,b=5)#1 (2, 3, 4) 5
#5.字典形参:实参可以传递数量无限的关键字实参
#目的: 实参可以传递数量无限的关键字实参
# 一般命名为**kwargs
def fun05(**kwargs):
print(kwargs)
fun05(a=1,b=2)#{'a': 1, 'b': 2}
参数从左到右的顺序
位置形参——>星号元组形参——>命名关键字形参——>双星号字典形参