python——列表、字典、元组、集合详解

0. 写在前面

  • 本博客会从底层详细阐述列表、字典、元组、集合的数据结构,让读者读完之后熟练掌握这四大python基础的数据结构,达到面试标准。

1. 列表

1.1 底层

  • 对于列表,它的底层是数据和指针(即索引)。**具体的,当我们初始化一个列表并赋值时,内存首先会为该列表开辟一块连续的内存空间用来存储数据的指针,即数据的地址,这些地址会帮我们找到数据。列表中的数据可以为任意类型。

1.2 列表常见的操作

在这里插入图片描述

  • 最常用的切片操作
list_arr=list([1,2,3])
list_arr[:2]

# result
[1,2]

可以看到索引不包含end值,这一点尤为重要

  • 另外要说一点,冒号: 用于定义分片、步长。
list_arr=list([1,2,3])
# 表示从列表list_array索引出第零个元素到最后一个但不包含最后一个的元素,并且步长为1
print(list_arr[0:-1:1])
# 步长为2
print(list_arr[0:-1:2])
# 当步长大于元素个数时,取第一个元素即可
print(list_arr[0:-1:3])

# result 
[1, 2]
[1]
[1]

1.3 列表的浅拷贝和深拷贝

1.3.1 如何理解浅拷贝和深拷贝

  • 通俗来讲,浅拷贝就是没复制好,复制的还和原来的连在一起,遵循“我变你就变”原则;深拷贝恰恰相反,指的是我完完全全复制了一份,并遵循“我变你不变”的原则。
  • 从底层来讲,浅拷贝指的是只复制了原始数据的指针索引,没有复制数据,所以复制过来的这份数据的指针依然指向原始数据,这就是“你变我就变”原则;深拷贝指的是既复制了指针又复制了数据,copy的这份完完全全有自己的数据和指针
    在这里插入图片描述

1.3.2 列表的浅拷贝与深拷贝

  • 直接赋值就是浅拷贝
  • 切片就是深拷贝

1.4 成员操作符in和not in

service = ['http', 'ssh', 'ftp']
service1 = ['mysql','firewalld']
print ('firewalld' in service)  #返回值为False
print ('firewalld' in service1)  #返回值为True
print ('firewalld' not in service)  #返回值为True

1.5 列表的小结

  • 不必死记,用到查就行,用得多了就熟悉了
    在这里插入图片描述

2. 元组

  • Tuple(元组)与列表相似,不同之处在于元组的元素不能修改
  • 元组在python开发中,有特定的应用场景用于存储一串信息,数据之间使用 “,” 分隔
  • 元组用 () 定义,列表中通常保存相同类型的数据,而元组中通常保存不同类型的数据,不可对元组内容进行增添删除。
# 元组本身不能增删改查,但是如果元组里面包含可变数据类型,可以间接修改元组的内容
t1 = ([1,2,3],4)
t1[0].append(4)
print (t1)

# result
([1,2,3,4],4)
  • 元组如果只有一个元素的时候,后面一定要加逗号,负责数据类型不确定
t2 = ('hello',)
t3 = (1,)
print (type(t2),type(t3))

# result
<type 'tuple'><type 'int'>
  • 元组比较简单,具体的操作完全可以参考列表

3. 字典

基础知识:哈希表

3.1 底层

在Python中,字典是通过散列表或说哈希表实现的。字典也被称为关联数组,还称为哈希数组等。也就是说,字典也是一个数组,但数组的索引是键经过哈希函数处理后得到的散列值

哈希函数的目的是:使键均匀地分布在数组中,并且可以在内存中以O(1)的时间复杂度进行寻址,从而实现快速查找和修改。

哈希表中哈希函数的设计困难在于将数据均匀分布在哈希表中,从而尽量减少哈希碰撞和冲突。由于不同的键可能具有相同的哈希值,即可能出现冲突,高级的哈希函数能够使冲突数目最小化。Python中并不包含这样高级的哈希函数,几个重要(用于处理字符串和整数)的哈希函数是常见的几个类型。通常情况下建立哈希表的具体过程如下:

  • 数据添加:把key通过哈希函数转换成一个整型数字,然后就将该数字对数组长度进行取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间里。
  • 数据查询:再次使用哈希函数将key转换为对应的数组下标,并定位到数组的位置获取value。

哈希函数就是一个映射,因此哈希函数的设定很灵活,只要使得任何关键字由此所得的哈希函数值都落在表长允许的范围之内即可。本质上看哈希函数不可能做成一个一对一的映射关系,其本质是一个多对一的映射,这也就引出了下面一个概念–哈希冲突或者说哈希碰撞。哈希碰撞是不可避免的,但是一个好的哈希函数的设计需要尽量避免哈希碰撞。

Python2中使用使用开放地址法解决冲突。

CPython使用伪随机探测(pseudo-random probing)的散列表(hash table)作为字典的底层数据结构。由于这个实现细节,只有可哈希的对象才能作为字典的键。字典的三个基本操作(添加元素,获取元素和删除元素)的平均事件复杂度为O(1)。

Python中所有不可变的内置类型都是可哈希的
可变类型(如列表,字典和集合)就是不可哈希的,因此不能作为字典的键。

3.2 字典常用得函数

  • key(),返回所有键
  • value(),返回所有值
  • items(),返回所有键值对
  • claer(),清空字典

4. 集合

4.1 底层

  • set集合和dict一样也是基于散列表的,只是他的表元只包含键的引用,而没有对值的引用,其他的和dict基本上是一致的,所以在此就不再多说了。并且dict要求键必须是能被哈希的不可变对象,因此普通的set无法作为dict的键,必须选择被“冻结”的不可变集合类:frozenset。顾名思义,一旦初始化,集合内数据不可修改。
  • 字典常用来去重。
  • set()函数:set(value)注意:创建一个空集合必须使用set(),不能使用{},因为{}是用来创建一个空字典
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

InceptionZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值