IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 10天学会Python系列-Day3 数据结构之列表 -> 正文阅读

[数据结构与算法]10天学会Python系列-Day3 数据结构之列表

1. 数据结构概述

这里的数据结构主要描述容器数据类型:列表, 字典, 集合四种容器数据类型, 它们都属于可变数据类型, 前面提到的数值类型和字符串类型、元组, 它们都属于不可变数据类型,不可以修改.

2. 列表

列表是容器数据类型,可存储多个元素,且支持不同类型数据,可修改,有序列表,可重复。

举例:

x = [1, 'abc', True, {"name":"Joe"}, 1, 2, ['7', '89']]
x

在这里插入图片描述
例子中展现了以下情况:

  • 不同的数据类型共存一个列表的情况:有数值类型、字符串、有列表、字典
  • 列表包含其他容器类型:字典{“name”:“Joe”}和列表[‘7’, ‘89’]
  • 列表展现了重复的数据,列表中存在2个1

2.1 定义列表

定义列表有2种方法:list()函数和[]列表运算符。

2.1.1 list()函数

首先看一下list()函数的描述:

list?

在这里插入图片描述从输出的描述信息中可知,list仅支持1个参数:

  • 可为空,为空时则创建一个空列表
x1 = list()
print(x1, type(x1))

在这里插入图片描述

  • 不为空时,参数必须是可迭代类型
    • 什么是可迭代对象呢?举个简单的例子,能够在for循环中遍历使用的都是可迭代类型,具体的可迭类型有字符串、列表、元组、字典。
x0 = list()                         # 无参数,空列表
print(x0, type(x0))
x1 = list("name")                   # 用字符串初始化列表
print(x1, type(x1))
x2 = list([1, 2, 'a', 'b', 'c'])    # 用列表初始化列表      
print(x2, type(x2))
x3 = list((1, 2, 3, 4))             # 用元组初始化列表
print(x3, type(x3))
d1 = {"name":"zsm", "age":18, "sex":"male"}
x4 = list(d1.keys())                  # 用字典初始化列表:对于key和value需要分别处理
x5 = list(d1.values())
print(x4, type(x4), x5, type(x5))

在这里插入图片描述

2.1.2 []列表运算符

x1 = []                 # 空列表
print(x1, type(x1))
x2 = [1, 2, 3, 4]       # 有元素的列表
print(x2, type(x2))

在这里插入图片描述

2.2 列表常用方法

x = [1, 2, 3, 4, 5]
dir(x)

[‘add’,
class’,
contains’,
delattr’,
delitem’,
dir’,
doc’,
eq’,
format’,
ge’,
getattribute’,
getitem’,
gt’,
hash’,
iadd’,
imul’,
init’,
init_subclass’,
iter’,
le’,
len’,
lt’,
mul’,
ne’,
new’,
reduce’,
reduce_ex’,
repr’,
reversed’,
rmul’,
setattr’,
setitem’,
sizeof’,
str’,
subclasshook’,
‘append’,
‘clear’,
‘copy’,
‘count’,
‘extend’,
‘index’,
‘insert’,
‘pop’,
‘remove’,
‘reverse’,
‘sort’]

使用dir函数列出列表可支持的方法和属性,从输出可知方法有’append’, ‘clear’, ‘copy’, ‘count’, ‘extend’, ‘index’, ‘insert’, ‘pop’, ‘remove’, ‘reverse’, ‘sort’。

  • 添加

    • li.append(x):向列表尾部添加一个元素
    x = [1, 2, 3, 4, 'abc', True]
    x.append(7)         # 在末尾插入一个对象        
    x
    

    [1, 2, 3, 4, ‘abc’, True, 7]

    • li.insert(index,object):向列表的指定位置插入一个元素
    x.insert(2, 'boy')  # 在索引为2的位置插入对象boy
    x
    

    [1, 2, ‘boy’, 3, 4, ‘abc’, True, 7]

    • li.extend(li2):合并,将参数列表中的元素合并到原列表中
    x2 = ['banana', 'apple']
    x.extend(x2)        # 注意:是将列表x2中的元素合并到x中,不是将x2整体合并到x中
    x
    

    [1, 2, ‘boy’, 3, 4, ‘abc’, True, 7, ‘banana’, ‘apple’]

  • 删除

    • li.pop(index):删除指定位置的一个元素
    y = x.pop(4)        # 取出列表中的元素4,取出后元素不再存于x中         
    print(x, y)
    

    [1, 2, ‘boy’, 3, ‘abc’, True, 7, ‘banana’, ‘apple’] 4

    • li.remove(object):删除指定内容的一个元素,object是要删除的元素,只能删除第一个
    x.append(2)         # 插入一个新的对象2到列表中
    print(x)
    x.remove(2)         # 删除一个值为2的对象,且仅删除第一个
    print(x)
    

    [1, 2, ‘boy’, 3, ‘abc’, True, 7, ‘banana’, ‘apple’, 2]
    [1, ‘boy’, 3, ‘abc’, True, 7, ‘banana’, ‘apple’, 2]

    • li.clear():清空列表中的所有元素
    x.clear()           # 清除对象
    x
    

    []

  • 序列

    • li.reverse():将列表反序,等同于[::-1]
    x = [1, 2, 3, 4, 'abc', True]
    print(x)
    x.reverse()         # 逆序
    print(x)
    

    [1, 2, 3, 4, ‘abc’, True]
    [True, ‘abc’, 4, 3, 2, 1]

    • li.sort():对列表排序,可按照升序或降序排列
    x = [1, 2, 3, 7, 8,3, 2,2]
    x.sort()
    print(x)
    

    [1, 2, 2, 2, 3, 3, 7, 8]

  • 其它

    • li.count(object):对列表中的某个元素进行计数
    x = [1, 2, 3, 7, 8,3, 2,2]
    x.count(2)
    

    3

    • li.index(object):获得列表中元素的索引,返回第一个匹配的索引
    x = [1, 2, 3, 7, 8,3, 2,2]
    x.index(2)
    

    1

2.3 列表推导式

列表推导式是一个根据条件从原列表快速生成新列表的简写方法,其语法为

[输出值 for 遍历的元素 in 列表变量 if 条件语句]

举例:快速删除列表中的数字3

x = [1, 2, 3, 4, 5, 3, 6, 7]
x = [i for i in x if i!=3]
print(x)

[1, 2, 4, 5, 6, 7]

2.4 变量的存储机制

Python中的一切都是对象,变量是对象的引用!对象存于堆中,变量存于栈中。

2.4.1 什么是堆、栈?

堆栈都存在与内存中,在运行时分配的内存空间。对象存于堆中,变量存于栈中, 堆区存变量值, 栈区存变量名。栈区存放变量名和其变量值的内存地址, 通过这个内存地址, 变量名可以找到变量值。

2.4.2 直接引用和间接引用

2.4.2.1 直接引用:变量名直接关联变量值

直接引用常见于整数类型和字符串类型,修改它们的值,其实已经指向了其它的对象。直接引用的数据类型也被称为不可变数据类型, 不可变数据类型在内存中存储的值仅存储一份,后续定义的变量如果值相等都指向用一个对象,即 x1 is x2 and x1 == x2为True.

变量名(变量值的地址)存于内存栈区,变量值存于堆区, 变量名直接关联变量值。

x = 10
y = 20
print(hex(id(x)), hex(id(y)))

0x7ff97c90f020 0x7ff97c90f160 # 从输出中可知,x,y指向两个不一样的对象

在这里插入图片描述当执行x = y 时,你会发现x已经指向了一个新的对象,和原来的对象链路已经断开了。

x = 10
y = 20
print(hex(id(x)), hex(id(y)))
x = y
print(hex(id(x)), hex(id(y)))

0x7ff97c90f020 0x7ff97c90f160
0x7ff97c90f160 0x7ff97c90f160 # 从输出中可知,x,y已经指向了同一个对象

在这里插入图片描述
注意:字符串的内容是不可以更改的,修改会直接报错!!!

name = "David"
name[2] = 'a'

TypeError Traceback (most recent call last)
C:\Users\ZHOUSH~1\AppData\Local\Temp/ipykernel_9084/4053774855.py in
1 name = “David”
2 name[2] = ‘a’
TypeError: ‘str’ object does not support item assignment

2.4.2.1 间接引用:变量名通过列表对象间接访问变量值

间接引用出现在容器类型里,如列表、元组、字典等。
定义列表变量l,其存储结构如图:变量l存储于栈区,变量l通过存储在堆区中列表对象内存地址访问列表对象,然后列表对象再通过其列表中存储的元素地址访问具体的变量值’a’ 和 ‘b’。

l = ['a', 'b']

在这里插入图片描述如果修改变量l[1]的值,例如l[1] = ‘c’,则列表的存储地址不会发生变化,但是列表对象第0个元素的地址会发生变化,其为字符’c’的内存地址,并指向字符对象’c’,但是整个过程变量l的地址不会发生变化.
在这里插入图片描述特别注意:间接引用变量既是值相等,这两个变量也不一定是同一个变量;而对于不可变数据类型,只要值相等,那么这两个变量一定是同一个变量.

x1 = [1, 2, 3, 4, 5, 3, 6, 7]
x2 = [1, 2, 3, 4, 5, 3, 6, 7]
x1 is x2
print(hex(id(x1)), hex(id(x2)))

0x2913b25ab08 0x2913cdf35c8

2.5 浅拷贝与深拷贝

  • 直接赋值:其实就是对象的引用(别名)。

  • 浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。

  • 深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。

2.5.1 直接赋值

其实就是对象的引用(别名)

l1 = [1, 'abc', [2, 3]]
l2 = l1
print(id(l1), id(l2))

2822815412936 2822815412936

l2直接指向l1引用的对象,l1和l2的内存地址是一样的, 存储结构如图.
在这里插入图片描述

2.5.2 浅拷贝

拷贝父对象,不会拷贝对象的内部的子对象。

import copy

l1 = [1, 'abc', [2, 3]]
l2 = copy.copy(l1)
print(id(l1), id(l2))
print('l1:', id(l1[0]), id(l1[1]), id(l1[2]))
print('l2:', id(l2[0]), id(l2[1]), id(l2[2]))

2822786373512 2822786371656 # l1和l2的内存地址不一样,是两个不一样的变量
l1: 140709513457408 2822710032120 2822785142088
l2: 140709513457408 2822710032120 2822785142088 # l1和l2的元素的内存地址是一样的, 包括元素中的列表变量(是直接指向过去的), 验证了仅拷贝父对象的描述.
在这里插入图片描述

2.5.3 深拷贝

copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。

import copy

l1 = [1, 'abc', [2, 3]]
l2 = copy.deepcopy(l1)
print(id(l1), id(l2))
print('l1:', id(l1[0]), id(l1[1]), id(l1[2]), id(l1[2][0]), id(l1[2][1]))
print('l2:', id(l2[0]), id(l2[1]), id(l2[2]), id(l2[2][0]), id(l2[2][1]))

2822786372360 2822815414472 # l1和l2的内存地址不一样,是不同的变量
l1: 140709513457408 2822710032120 2822786363528 140709513457440 140709513457472
l2: 140709513457408 2822710032120 2822786366024 140709513457440 140709513457472

l2对l1进行了深拷贝,直至数据类型为不可变类型为止.
从输出中可以看到:

  • l1和l2的内存地址不一样了,是不同的变量;
  • l1和l2的前2个成员变量的内存是一样的, 因为它们直接引用的不可变数据类型;
  • 第3个成员变量为一个列表,深拷贝时创建了一个新的列表变量,从输出可知l1[2]的内存地址为2822786363528, l2[2]的内存地址为2822786366024.
  • 但l1[2]和l[3]列表中的元素的内存地址又变为一样的了,因为它们都是不可变数据类型,指向同一个对象(注:不可变数据类型仅在内存中存储一份).
    在这里插入图片描述
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-22 19:01:27  更:2022-04-22 19:05:03 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 7:31:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码