Python8-10

第八章

什么是元组

元组是Python内置的数据结构之一,是一个不可变序列

不可变序列与可变序列

不可变序列:字符串、元组,不可变序列没有增删改操作

可变序列:字典、序列, 可变序列可以对序列执行增删改操作,对象地址不发生改变

元组的创建方式

1、使用小括号 t = (“hello”, 9, “python”)

2、使用内置函数tuple() t = tuple((“ccc”, 98, “aaa”))

3、只包含一个元组的元素需要使用逗号和小括号 t = (10, )

为什么要将元组设计成不可变序列:在多任务环境下,同时操作对象时不需要加锁

注意事项:

元组中存储的是对象的引用

a)如果元组中对象本身是不可变对象,则不能再引用其他对象

扫描二维码关注公众号,回复: 12912690 查看本文章

b)如果元组中对象本身是可变对象,则可变对象的引用不允许改变,但数据可以改变

元组的遍历

元组是可迭代对象,所以可以使用for…in进行遍历

t =(10, 20,“lll”)

for item in t:

​ print(item)

什么是集合

集合是Python语言提供的内置数据结构,与列表、字典一样都属于可变类型的序列,集合是没有value的字典。

集合的创建

1、直接{ } s ={“python”, 98, “hello”}

2、使用内置函数set()

集合的增、删、改、查操作

集合元素的判断操作:in或not in

集合元素的新增操作:调用add()方法,一次添加一个元素 调用updata()方法至少添加一个元素

集合元素的删除操作:调用remove()方法,一次删除一个指定元素,如果指定的元素不存在抛出KeyError

调用discard()方法,一次删除一个指定元素,如果指定的元素不存在不抛异常

调用pop()方法,一次只删除一个任意元素,不能添加参数

调用clear()方法,清空集合

两个集合之间的关系

1、两个集合是否相等,可以使用运算符==或!=进行判断

2、一个集合是另一个集合的子集,可以调用方法issubset进行判断

3、一个集合是另一个集合的超集,可以调用方法issuperset

4、两个集合是否没有交集,可以调用方法isidisjoint进行判断

集合的数学操作:交集、并集、差集、对称差集

# 集合的数学操作
s1 = {10, 20, 30, 40, 50, 60}
s2 = {10, 20, 30, 40, 90, 100, 80}
"""
两个集合的交集,可以调用intersection()方法和&
"""
print(s1.intersection(s2))
print(s1 & s2)
"""
两个集合的并集,可以调用union()方法和 |
"""
print(s1.union(s2))
print(s1 | s2)

"""
两个集合的差集,差集为所在集合减去交集的部分,可以调用difference()方法和-
"""
print(s1.difference(s2))
print(s1-s2)

"""两个集合的对称差集,可以调用symmetric_difference()方法和^"""
print(s1.symmetric_difference(s2))
print(s1 ^ s2)

集合生成式

用于生成集合的公式

{i*i for i in range(1,10)}

i*i:表示集合的表达式 i:自定义变量 range():可迭代对象

注意:没有元组生成式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z9xwxHBq-1616079347876)(D:\Program Files\学习笔记\python学习笔记\截图\列表、字典、元组、集合.PNG)]

第九章

字符串的驻留机制

字符串:在python中字符串是基本数据类型,是一个不可变的字符序列

什么叫字符串驻留机制?

仅保存一份相同且相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,Python的驻留机制对相同字符产只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋值给新创建的变量

驻留机制的几种情况(交互式)

1、字符串的长度为0或1时

2、符合标识符的字符串

3、字符串只在编译时进行驻留,而非运行时

4、[-5,256]之间的整数数字

sys中的intern方法强制2个字符串指向同一个对象,pycharm对字符串进行了优化处理

字符串驻留机制的优缺点

1、当需要值相同的字符串时,可以直接从字符串池里拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是比较影响性能的

2、在需要进行字符串拼接时建议使用str类型的join方法,而非+,因为join()方法是先计算出所有字符串中的长度,然后再拷贝,只new一次对象,效率要比“+”效率高

字符串的常用操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wWiUPnhY-1616079347878)(D:\Program Files\学习笔记\python学习笔记\截图\字符串的查询操作.PNG)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ejGG0U4R-1616079347879)(D:\Program Files\学习笔记\python学习笔记\截图\字符串的大小写转换.PNG)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T4bl0x8i-1616079347882)(D:\Program Files\学习笔记\python学习笔记\截图\字符串内容的对齐操作.PNG)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lzV9KUnt-1616079347883)(D:\Program Files\学习笔记\python学习笔记\截图\字符串的劈分操作.PNG)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ixpNcsSt-1616079347884)(D:\Program Files\学习笔记\python学习笔记\截图\判断字符串操作的方法.PNG)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vhCjsgCw-1616079347885)(D:\Program Files\学习笔记\python学习笔记\截图\字符串操作的其他方法.PNG)]

字符串的比较

运算符:>,>=,<,<=,==,!=

比较规则:首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次比较下去,知道两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串中的所有后续字符将不再被比较

比较原理:两个字符进行比较时,比较的是其ordinal value(原始值),调用内置函数ord可以得到指定字符的ordinal value。与内置函数ord对应的是内置函数char,调用内置函数char时指定ordinal value,可以得到其对应的字符

print("apple" > "app") # True
print("apple" > "banana") # False,相当于97<98
# 当然可以使用内置函数可以得到字符的原始值
print(ord("a"), ord("b")) # 97  98

# 也可以使用与ord对应的内置函数char,将对应的值得到对应的字符
print(chr(97), chr(98)) # a  b
"""== 与 is
==比较的是value值,is比较的是两个对象的地址值
"""
a = b = "python"
c = "python"
print(a is b)   #True
print(a is c)   #True
print(b is c)   #True
print(id(a), id(b), id(c))

字符串的切片操作

字符串是不可变序列,不具备增、删、改等操作,而且切片操作会产生新的对象

print("------------切片[start:end:step]--------------------------")
# 对s从1开始到5结束,步长为1进行切片
print(s[1:5:1])
# 对s从0开始到字符串最后结束,步长为2进行切片
print(s[::2])
# 默认从字符串的最后一个元素开始,到字符串的第一个元素结束,因为不成为负数
print(s[::-1])
# 从索引为-6开始,到字符串的最后一个元素结束,步长为1
print(s[-6::1])

格式化字符串

格式化字符串的两种方式

1、%作占位符 %s:字符串 %i或%d:整数 %f:浮点数

name = "shangsan"
age = 20
# 字符串格式化的第一种方式,使用占位符%,其中 单独的%是固定的格式
print("我叫%s,今年%d" % (name, age))

# 字符串格式化的第二种方式 ,使用{},花括号中指定的是索引,并且还使用到format函数
print("我叫{0},今年{1}岁".format(name, age))

# 字符串格式化的第三种方式,使用f-string
print(f"我叫{name},今年{age}岁")
print("%10d" % 99)
print("hellohello")
# .3表示小数点后三位
print("%.3f" % 3.1415)
# 同时表示宽度和精度
print("%10.3f" % 3.14159)

2、使用{}

print("{0}".format(3.14159))

# .3表示的是一共是3位数
print("{0:.3}".format(3.14159))
# .3f表示的是3位小数
print("{0:.3f}".format(3.14159))

# 同时设置宽度和精度,宽度是10,3位小数
print("{0:10.3f}".format(3.14159))

字符串的编码转换

为什么需要字符串的编码转换?

将字符以unicode表示通过bytes转换为二进制数据,再解码显示再计算机上

编码与解码的方式

·编码:将字符串转换为二进制数据(bytes)

·解码:将bytes类型的数据转换为字符串类型

s = "天涯共此时"
# 在GBK这种编码格式中,一个中文占两个字节
print(s.encode(encoding="GBK"))
# 在UTF-8这种编码格式中,一个中文占3个字节
print(s.encode(encoding="UTF-8"))

print("------下面是解码-------")
byte = s.encode(encoding="GBK")
# 解码需要用到byte的decode方法,并且是以什么方式编的码就要以什么方式解码
print(byte.decode(encoding="GBK"))
byte = s.encode(encoding="UTF-8")
print(byte.decode(encoding="UTF-8"))

第十章

函数的创建和调用

什么是函数?

函数就是执行特定任务和完成特定功能的一段代码

为什么需要函数?

1、复用代码

2、隐藏实现细节

3、提高可维护性

4、提高可读性便于调试

函数的创建 :

def 函数名 ([输入参数]):

​ 函数体

​ [return xxx]

def calc(a, b):
    c = a +b
    return c
result = calc(10, 20)
print(result)

函数的参数传递

函数调用的参数传递

1、位置实参:根据形参对应的位置进行实参传递

2、关键字实参:根据形参名称进行参数传递

res = calc(b=10, a=20)
print(res)

=号左侧变量的名称称为关键字参数,传递时就不会以对应的位置进行传递,而是通过关键字

def fun(args1, args2):
    print("args1", args1)
    print("args2", args2)
    args1 = 100
    args2.append(10)
    print(args1)
    print(args2)

n1 = 10
n2 = [11, 22, 33]
print("n1", n1)
print("n2", n2)
# 位置传参,args1,args2是形式参数,n1,n2是实际参数,可以发现,实际参数和形式参数的名称可以不一致
fun(n1, n2)
print("n1", n1)
print("n2", n2)
"""
在函数的调用过程中,进行参数的传递,如果是不可变对象,在函数
体内的修改不会影响实参的值,其中字符串是不可变对象,而列表是可变序列,所以添加会
影响原始的值,故最后打印出来的是[11,22,33,10]
"""

函数的返回值

函数返回多个值时,结果为元组

print(bool(0))
print(bool(1))

# 可以知道0的布尔值为False
# 非0的布尔值为True

def fun(num):
    # 声明一个odd列表,用于存储奇数
    odd = []
    # 声明一个even列表,用于存储偶数
    even = []
    for i in num:
        if i%2:
            odd.append(i)
        else:
            even.append(i)
    return odd, even

# 函数的调用
list = [10, 29, 34, 23, 44, 53, 55]
print(fun(list))

"""函数的返回值
1、如果函数没有返回值【函数执行完毕之后,不需要给调用处提供数据】 return可以省略不写
2、函数的返回值,如果是1个 ,函数返回原类型
3、函数的返回值,如果是多个,返回的结果为元组
"""
def fun1():
    print("hello")
fun1()
def fun2():
    return "hello"
res = fun2()
print(res)

def fun3():
    return "hello", "world"
print(fun3())

"""函数在定义时,是否需要返回值视情况而定
"""

函数的参数定义

函数定义默认值参数

函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参

# b就称为默认值参数
def fun(a, b=10):
    print(a, b)
# 函数调用
fun(100)
fun(20, 30)

个数可变的位置参数

定义函数时,可能无法事先确定传递为的位置实参的个数时,使用可变的位置参数,使用*定义个数可变的位置形参,结果为一个元组

个数可变的关键字形参

定义函数时,无法事先确定传递的关键字实参的个数时,可以使用可变的关键字形参,使用**定义个数可变的关键字形参,结果为一个字典

# 函数的定义时的可变位置参数
def fun(*args):
    print(args)
fun(10)
fun(10, 20)

def fun1(**args):
    print(args)
fun1(a=10)
fun1(a=10, b=20, c=30)

"""个数可变的位置参数只能有一个,个数可变的关键字参数也只能有一个,不然会报错

在一个函数的定义过程当中,既有个数可变的关键字形参,也有个数可变的位置参数
要求个数可变的位置参数放在个数可变的关键字参数之前 
def fun(*args,**args):
    pass
"""

变量的作用域

程序代码能访问该变量的区域,根据变量的有效范围可分为

1、局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会成全局变量

2、全局变量:函数体外定义的变量,可用于函数内外

"""这里的c就是局部变量,形式参数a,b也是局部变量,只能在函数内使用
"""
def fun(a, b):
    c = a+b
    print(c)

"""name的作用范围为函数的内部和外部都可以使用,所以name是全局变量
"""
name = 'qq'
print(name)
def fun2():
    print(name)
fun2()

def fun3():
# 函数内部定义的是局部变量,当变量被global修饰时,就变成了全局变量
    global age
    age = 20
    print(age)
fun3()
print(age)

递归函数

什么是递归函数?

如果在一个函数的函数体内调用了该函数本身,这个函数就称为递归函数

递归的组成部分?

递归调用与递归终止条件

递归的调用过程

1、每递归调用一次函数,都会在栈内存分配一个栈帧

2、没执行完一次函数,都会释放相应的空间

递归的优缺点

缺点:占内存多,效率低下

优点:思路和代码简单

使用递归求6的阶乘代码实现

def fac(n):
    if n == 1:
        return 1
    else:
        return n*fac(n-1)
print(fac(6))

使用递归来求斐波那契数代码实现:

# n就是我们要求的斐波那契额的数
def fib(n):
    if n == 1:
        return 1
    elif n == 2:
        return 1
    else:
        return fib(n-1)+fib(n-2)
# 斐波那契第六位上的数字
result = fib(6)
print(result)

print("----------------")
# 输出前6位斐波那契数
for i in range(1, 7):
    print(fib(i))

猜你喜欢

转载自blog.csdn.net/qq_48424500/article/details/114993185
今日推荐