• Python(8)序列


    序列

    • 序列是Python中最基本的一种数据结构
    • 序列用于保存一组有序的数据,所有的数据在序列当中都有一个唯一的位置(索引) 并且序列中的数据会按照添加的顺序来分配索引
    • 序列的分类:
      • 可变序列(序列中的元素可以改变)
        • 列表(list)
      • 不可变序列(序列中的元素不可以改变)
        • 元组(tuple)
        • 字符串(str)

    切片

    单独取值

    
    students = ["孙悟空", "猪八戒", "沙和尚", "唐三藏"]
    
    print(students[0])
    
    # 切片可以是负数(从尾部取)
    
    print(students[-1])
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    范围取值

    • 列表[起始:结束:步长]
      • 通过切片获取元素时,会包括起始位置的元素,但不会包括结束位置的元素。
      • 做切片操作时,会返回一个新的序列,不会影响之前的序列
      • 起始(序列的最开始)和结束(序列的最后位置)位置的索引可以省略不写
      • 步长表示,每次获取元素的间隔(默认为1)
      • 步长不可以是0,但可以是负数
    students = ["孙悟空", "猪八戒", "沙和尚", "唐三藏"]
    print(students[1:3])  # ['猪八戒', '沙和尚']
    print(students[1:-1])  # ['猪八戒', '沙和尚']
    print(students[1:])  # ['猪八戒', '沙和尚', '唐三藏']
    print(students[:3])  # ['孙悟空', '猪八戒', '沙和尚']
    
    a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    print(a[0:6:2])  # [1, 3, 5]
    print(a[::-1])  # [9, 8, 7, 6, 5, 4, 3, 2, 1]
    print(a[::-2])  # [9, 7, 5, 3, 1]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    序列于+ 和 ×

    a = [1, 2, 3]
    b = [4, 5, 6]
    print(a + b)
    
    c = [1, 2, 3] * 5
    print(c)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    序列和 in 和 not in

    • in就是用来检测指定元素是否存在于序列中
      • 如果在 True 如果不在就是False
    • not in 用来检测元素是否不在序列中
    a = [1, 2, 3]
    print(1 in a)  # True
    print(4 not in a)  # True
    
    • 1
    • 2
    • 3

    len() 获取序列元素的个数

    min() 获取序列中的最小值

    max() 获取序列中的最大值

    index() 获取指定元素第一次出现时的索引

    index(“str”,1,5)在索引 1 到 5 之间的位置 查找指定元素

    count() 统计指定元素出现的次数

    map()、filter()

    • map
      • map() 函数会根据提供的函数对指定的可迭代对象的每个元素进行运算,并将返回运算结果的迭代器
    • filter
      • filter()函数会根据提供的函数对指定的可迭代对象的每个元素进行运算,并将运算结果为True的元素,以迭代器的形式返回
    # 定义一个列表(可迭代对象)
    s = [1, 2, 3, 4]
    
    
    # 定义一个函数,这个函数的功能是,如果是偶数则返回数字本身,如果不是偶数则返回None
    def odd(num):
        if num % 2 == 0:
            return num
        else:
            return None
    
    
    # map(odd,s) 第一个参数是函数名,第二个参数是可迭代对象
    # 由于返回的是一个迭代器,我们需要将其转换成一个列表,所以使用list转换
    map_lise = list(map(odd, s))
    
    # filter(odd,s) 第一个参数是函数名,第二个参数是可迭代对象
    # filter只会返回结果为True的值,None是空性,所以为False不返回,这里就把偶数过滤了出来
    filter_list = list(filter(odd, s))
    
    print(map_lise)
    print(filter_list)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    列表

    • 列表是Python中的一个对象
    • 列表中可以保存多个有序的数据,列表是用来存储对象的对象

    列表的方法

    append

    a = ["孙悟空"]
    a.append("猪八戒")
    print(a)
    
    • 1
    • 2
    • 3

    insert

    a = ["孙悟空"]
    a.insert(0, "唐三藏")
    print(a)
    
    • 1
    • 2
    • 3

    extend

    a = ["孙悟空"]
    # a.extend(["白龙马","沙和尚"])
    a += ["白龙马", "沙和尚"]
    print(a)
    
    • 1
    • 2
    • 3
    • 4

    clear()

    a = ["孙悟空"]
    a.clear()
    print(a)
    
    • 1
    • 2
    • 3

    pop,remove

    pop 按照索引删除,如果不添加索引则删除最后一个元素

    a = ["孙悟空","猪八戒"]
    a.pop(0) # ['猪八戒']
    a.pop() # ['孙悟空']
    
    • 1
    • 2
    • 3

    remove 删除目标元素

    a = ["孙悟空","猪八戒"]
    a.remove("猪八戒") # ["孙悟空"]
    
    • 1
    • 2

    reverse

    a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    a.reverse() # 列表翻转
    
    • 1
    • 2

    sort

    a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    a.sort()   # 默认升序
    
    a.sort(reverse=True)   # reverse = True 表示为降序
    
    • 1
    • 2
    • 3
    • 4
    • 5

    列表循环

    while循环

    a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    count = 0
    
    while count < len(a):
    
        print(a[count])
        count += 1
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    for循环

    a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    for i in a:
        print(i)
    
    • 1
    • 2
    • 3
    • 4

    列表的拷贝

    列表中存储的只是对象的引用并不是对象本身,变量也同理。

    • x 是变量 存储的是列表的引用

    • 列表中的1 2 3 也是引用并不是本身

    • 当 将x赋值给y后 赋值的也是引用并不是值,不是值!不是值!!
      在这里插入图片描述

    • 当我们修改变量 y 的值后,再输出y和x发现x也被修改,因为他们是同一个引用

    代码如下所示:

    x = [1, 2, 3]
    y = x
    y[1] = 1
    print(y)  # [1, 1, 3]
    print(x)  # [1, 1, 3]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    我们只可以使用copy或切片来实现列表的值的复制

    x = [1, 2, 3]
    y = x.copy()  # y = x[:]
    y[2] = 1
    print(y)
    print(x)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    但当我们使用嵌套列表时就又不管用了

    x = [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
    y = x.copy()
    y[1][1] = 3
    print(y)  # [[1, 2, 3], [1, 3, 3], [1, 2, 3]]
    print(x)  # [[1, 2, 3], [1, 3, 3], [1, 2, 3]]
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这时我们可以使用深拷贝

    import copy
    
    x = [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
    y = copy.deepcopy(x)
    y[1][1] = 3
    print(y)  # [[1, 2, 3], [1, 3, 3], [1, 2, 3]]
    print(x)  # [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    列表推导式

    思考

    将一个由数字组成的列表中的数字全部翻倍

    原始写法

    a = [1, 2, 3, 4, 5, 6]
    for i in range(len(a)):
        a[i] = a[i] * 2
    
    • 1
    • 2
    • 3

    推导式

    a = [1, 2, 3, 4, 5, 6]
    a = [i * 2 for i in a]
    print(a)
    
    • 1
    • 2
    • 3

    推导式语法
    [expression for target in iterable]

    [表达式 for 目标 in 可迭代对象]

    小案例

    将0-9存到列表

    将列表 0-9 的数值分别+1后填入列表

    # 将0-9存到列表
    print([i for i in range(10)])
    
    # 将列表 0-9 的数值分别+1后填入列表
    print([i + 1 for i in range(10)])
    
    • 1
    • 2
    • 3
    • 4
    • 5

    推导式的嵌套

    将 [[1,2,3],[4,5,6],[7,8,9]] 二位数组展开

    matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
    print([col for i in matrix for col in i])
    
    • 1
    • 2

    推导式条件添加

    [“A”, “B”, “C”, “A”] 将列表中的 A 存入新列表

    words = ["A", "B", "C", "A"]
    print([word for word in words if word == "A"])
    
    • 1
    • 2

    推导式嵌套时添加条件

    # 推导式
    print([[x, y] for x in range(10) if x % 2 == 0 for y in range(10) if y % 3 == 0])
    
    # 相同作用的 for 循环
    b = []
    for x in range(10):
        if x % 2 == 0:
            for y in range(10):
                if y % 3 == 0:
                    b.append([x, y])
    print(b)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    元组

    元组也是序列,是不可变序列

    可以使用序列的所有方法

    相较于列表来说,最大的区别就是不可变

    元组有推导式么?

    元组没有推导式

    s = (1, 2, 3, 4)
    
    # 列表推导式
    print([i for i in s])  # [1, 2, 3, 4]
    
    # 这个返回的是一个生成器
    print((i for i in s))  #  at 0x0000021102C619E0>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    如何生成一个只有一个元素的元组?

    为什么会有这个问题呢?请看以下案例

    s = (123)
    print(type(s))  # 
    
    # 正确写法 在元素后面加一个逗号
    s = (123,)
    print(type(s))  # 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    元组的打包和解包

    打包就是简单的创建一个元组,而解包就是用对应数量的变量接收

    # 打包
    s = (1, 2, 3)
    
    # 解包
    a, b, c = s
    
    print(a)  # 1
    print(b)  # 2
    print(c)  # 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    不仅是元组可以,所有序列都可以

    # 字符串
    s = "123"
    a, b, c = s
    print(a)  # 1
    print(b)  # 2
    print(c)  # 3
    
    # 列表
    s = [1, 2, 3]
    a, b, c = s
    print(a)  # 1
    print(b)  # 2
    print(c)  # 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    我们还可以使用 * 去用更少的变量解包

    # 打包
    s = (1, 2, 3, 4, 5, 6)
    
    # 解包
    a, b, *c = s
    
    print(a)  # 1
    print(b)  # 2
    print(c)  # [3, 4, 5, 6]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    震惊元组不可变被推翻!竟然可以修改!

    先来看案例:

    a = ([1, 2, 3], [4, 5, 6])
    a[0][0] = 9
    print(a)  # ([9, 2, 3], [4, 5, 6])
    
    • 1
    • 2
    • 3

    通过观察可以发现,元组中的列表确实变了!不是不可变的么?这是为什么?

    元组中的变量发生改变是真实发生的,但元组并未改变。

    当我们使用索引 a[0] 获取到的元素获取到的是列表,我们改变的是列表第0个位置的值,列表就是可变,所以可以理解为列表的id并未改变。

    看如下代码你就明白了

    a = ([1, 2, 3], [4, 5, 6])
    print("元组id", id(a))  # 元组id 1979716155456
    print("未改变前列表id", id(a[0]))  # 未改变前列表id 1977868906304
    
    a[0][0] = 9
    print(a)  # ([9, 2, 3], [4, 5, 6])
    
    print("改变后列表id", id(a[0]))  # 改变后列表id 1977868906304
    print("改变后元组id", id(a))  # 改变后元组id 1979716155456
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    字符串

    字符串也属于不可变序列,拥有所有不可变序列的所有特性

    练习

    判断一个字符串是不是回文数

    • 回文数
      • 正着反着都一样
      • 例如:“12321”
    s = "12321"
    
    print("是回文数") if s == s[::-1] else print("不是回文数")
    
    • 1
    • 2
    • 3

    迭代器和可迭代对象

    • 迭代器
      • 迭代器肯定是一个可迭代对象
      • 迭代器不可以重复使用,是一次性的
    • 可迭代对象
      • 迭代对象是可以重复使用的
    s = [1, 2, 3, 4]  # 可迭代对象
    
    
    def odd(num):
        if num % 2 == 0:
            return num
        else:
            return None
    
    
    map_iter = map(odd, s)  # 返回一个迭代器
    
    # 当我们使用了这个迭代器后
    for i in map_iter:
        print(i)
    
    # 再次使用迭代器为空
    print(list(map_iter))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    我们还可以使用iter()将一个可迭代对象转换成一个迭代器

    x = [1, 2, 3, 4]
    y = iter(x)
    
    print(type(x))  # 
    print(type(y))  # 
    
    print(list(y))  # [1, 2, 3, 4]
    print(list(y))  # []
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    next()

    next() 针对迭代器使用的 作用是将迭代器中的对象逐个提取出来

    x = [1, 2, 3, 4]
    y = iter(x)
    
    print(next(y))  # 1
    print(next(y))  # 2
    print(next(y))  # 3
    print(next(y))  # 4
    
    print(next(y))  # 报错,因为迭代器中没有元素了
    """
    Traceback (most recent call last):
      File "D:\work\python_work_space\attend-classclass-begins\teacher\python_S\test.py", line 8, in 
        print(next(y))  
    StopIteration
    """
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    我们可以使用next()第二个参数改变没有元素时的返回值

    x = [1, 2, 3, 4]
    y = iter(x)
    
    print(next(y))  # 1
    print(next(y))  # 2
    print(next(y))  # 3
    print(next(y))  # 4
    
    print(next(y,"没有了!别下一个了!"))  # 没有了!别下一个了!
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    Oracle表空间、用户详解
    移动终端数据业务高安全通信方案研究
    【数据结构】时间复杂度与空间复杂度
    记一次RocketMQ消费非顺序消息引起的线上事故
    一个 .net 8 + Azure 登录 + Ant Design Blazor 的基本后台框架
    Redis常用指令汇总
    nvm:轻松管理多个 Node 版本 | 开源日报 No.80
    时空智友企业流程化管控系统文件存在任意文件上传漏洞 附POC
    算法提升:图的最小生成树算法-克鲁斯卡尔(Kruskal)
    Java——聊聊JUC中的CompletableFuture
  • 原文地址:https://blog.csdn.net/gtd54789/article/details/127826932