了解Python中的list和dict的一些高级用法

本文深入探讨Python中List与Dict的高级用法,包括切片、拷贝、转换技巧及其底层实现原理,适合希望提升Python编程技能的开发者阅读。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

list和dict是python中常用的列表和字典。
这里讨论一下他们的原理及一些高级用法,供大家查询参考。

list的切片

list的切片格式为:

list[start:end:step]

其中step如果没有,则默认为1
下面举例说明:
先定义一个list:

list = [1,2,3,4,5,6,7,8,9]

那么list[1:6:2],就表示从1位置开始到3位置结束,间隔2,结果如下:

list[1:6:2]
[2, 4, 6]

注意:list的切片操作会返回一个新的列表,切片并不会改变原list本身。

dict的浅拷贝及深拷贝

什么是dict(字典)的浅拷贝和深拷贝?
如果我们在已有指针的情况下,增加一个指针指向已经存在的内存,称为浅拷贝。
如果我们增加一个指针的同时也新增了内存,并且新指针指向到新内存,称为深拷贝。

注意区分dict的浅拷贝及深拷贝的区别。
下面举个例子说明一下:

import copy   

dict = {"a":{"a1":"a123"}, "b":{"b1":"b123"}}
a_dict = dict.copy()                # 浅拷贝
a_dict["a"]["a1"]="newa123"

b_dict = copy.deepcopy(dict)        #深拷贝
b_dict["b"]["b1"]="newb123"

print(dict)
print(a_dict)
print(b_dict)

浅拷贝会替换掉原来的的dict,而深拷贝会新建一个dict,不会替换掉原来的dict。

list转化为dict

在python3的环境下,list转化成dict。
下面每一步都复制了执行语句后的结果。便于参考。
先定义一个list:

>>> list = ["a1", "b1"]

通过dict.fromkeys方法创建一个新字典:

>>> dict_list = dict.fromkeys(list,{"aa1":"1234556"})
>>> dict_list
{'a1': {'aa1': '1234556'}, 'b1': {'aa1': '1234556'}}

通过get方法获取value的值,注意get的用法:

>>> value = dict_list.get("a1")
>>> value
{'aa1': '1234556'}

用update方法来修改dict:

>>> dict_list.update(a1="new123",b1="bbb123")
>>> dict_list
{'a1': 'new123', 'b1': 'bbb123'}

>>> dict_list.update((("a1","aaa123"),("b1","bbb123")))
>>> dict_list
{'a1': 'aaa123', 'b1': 'bbb123'} 

完整代码如下:

list = ["a1","b1"]
dict_list = dict.fromkeys(list,{"aa1":"1234556"})
value = dict_list.get("a1")
dict_list.update(a1="new123",b1="bbb123")
dict_list.update((("a1","aaa123"),("b1","bbb123")))

list和dict的实现原理

当我们定义一个list或者dict的时候,数据会存入内存中。
在list中随着list数据的增大,查找时间会增大,
而在dict中查找元素的时候,不会随着dict的增大而增大,
所以说dict查找的性能远大于list。

那么,为什么dict中查找元素的时候,时间会比查找list少呢?
dict背后实现原理是哈希表(hash),其特点是:
1、dict的key或者set的值,都必须是可以hash的,
就是说对不可变对象都是可hash的,比如str, fronzenset(不可变集合), tuple,
如果是自己实现的类,我们可以在类中加__hash__,这样我们的对象就是可hash对象
2、dict的内存花销大,但是查询速度快,自定义对象或python内部的对象都是用dict包装的。
3、dict的存储顺序和元素添加顺序有关。
4、添加数据有可能改变已有数据的顺序。
当表元(列表中的元素)小于三分之一,就会重新申请空间,在重新分配内存中,有可能重新改变顺序。

字典与列表dict和list
字典通过偏移量直接寻址。
查找原理大致步骤如下,原谅我不会画图:
1、计算键的散列值(哈希值)–>
2、使用散列值的一部分来定位散列表中的一个表元 -->
3、表元为空 --> 抛出keyerror
4、表元不为空 -->
5、判断键是否相等 -->
如果是 --> 返回表元里的值
如果否,表示散列冲突 -->
6、使用散列值的另一部分来定位散列表中的另一行 -->
7、表元为空 -->
8、返回前面第3步骤继续循环

set集合和frozenset集合

1、set集合是可变集合,可以添加,可以删除。
set集合没有hash值,它是无序的。不支持序列,不记录元素的位置。
2、frozenset集合是不可变集合,不能添加,一旦创建就不能删除。
frozenset可以作为字典的key,也可以作为其他集合的元素。

他们特点都是无序,不能重复的,如:
set集合是无序且不能重复的:

>>> s=set('abcdcee')
>>> s
{'d', 'e', 'b', 'a', 'c'}

set集合可以添加:

>>> s.add('g')
>>> s
{'d', 'e', 'b', 'a', 'c', 'g'}

frozenset集合也是是无序且不能重复的:

>>> ss=frozenset('123332')
>>> ss
frozenset({'3', '1', '2'})

注意frozenset集合是没有add方法的,也就是不能添加。

通过update来给set集合添加集合:

>>> ss=set('zyxzce')
>>> ss
{'e', 'z', 'y', 'x', 'c'}
>>> s.update(ss)
>>> s
{'d', 'e', 'z', 'y', 'b', 'x', 'a', 'c', 'g'}

difference可以查看集合之间的区别:

>>> s.difference(ss)
{'g', 'b', 'a', 'd'}

list和dict的类继承

list和dict本身也是类。
在我们定义类的时候,通常不建议继承list和dict。
因为在某些情况之下,用c语言写的dict,不会调用我们自定义的重新覆盖的方法。
如果实在要继承,可以用UserDict,如:

from collections import UserDict

class MyDict(UserDict):
    def __setitem__(self, key, value):
        super().__setitem__(key, value*2)
        
mydict = MyDict(a=1)

不建议的用法,这里只是顺带一提。

### Python 中 `list` `dict` 的用法及区别 #### 列表(List) 列表是Python中的一种有序、可变的数据结构,能够存储任意类型的元素。这意味着可以在同一个列表内混合不同类型的数据[^2]。 创建一个简单的列表如下: ```python my_list = ['apple', 'banana', 'cherry'] ``` 访问列表中的元素可以通过索引实现,第一个元素的索引为0: ```python first_element = my_list[0] ``` 修改列表内的某个元素也很容易做到: ```python my_list[1] = "blueberry" ``` 还可以向列表添加新项或删除现有项: ```python my_list.append('date') # 添加元素到末尾 del my_list[0] # 删除指定位置的元素 ``` #### 字典(Dictionary) 字典则是无序、键值对形式存在的容器类型,在版本3.7之后保持插入顺序不变。每个条目由一对组成——一个是唯一的键(key),另一个关联的是该键对应的值(value)[^1]。 初始化一个包含几对学生年龄记录的字典实例: ```python ages_dict = {"Alice": 30, "Bob": 24} ``` 获取特定人的年龄信息只需提供相应的名字作为键即可获得其对应的价值: ```python alice_age = ages_dict["Alice"] ``` 更新某个人的信息同样简单明了: ```python ages_dict.update({"Charlie": 29}) # 新增/更改条目 ``` #### 使用差异对比 - **数据存取方式**: 对于`list`, 是通过整数型的位置编号来定位;而`dict`则依赖独一无二的字符串或其他不可变得对象充当key来进行查找。 - **性能特点**: 当涉及到频繁查询操作时,如果已知确切的关键字,则`dict`通常会比遍历整个数组寻找目标更高效得多。但是当只需要按顺序处理一组项目而不关心它们的身份标识符的情况下,`list`可能是更好的选择因为它的内存占用相对较小一些。 - **应用场景举例** - `list`: 存储一系列具有相同性质的事物集合,比如一周七天的名字或者是学生名单等; - `dict`: 表达实体之间的映射关系,如国家名称与其首都城市之间的一一对应关系或是配置文件解析后的参数设置等等[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值