突破常规:揭秘我在学习 Python 容器时的新收获

前言

Python代码也写了好长时间了,回过头来再看基础知识,还是颇有收获,这里记录一下自己再看容器类型的收获

元组

我们都知道定义元组像下面这样使用()

ini 复制代码
t = (1, 2, 3)

其实,()不是定义元组的关键标志,我们删除两侧的括号,像这样

bash 复制代码
t = 1, 2, 3
print(type(t)) # <class 'tuple'>

可以看到,这样也是一个元组,逗号才是解释器判定为元组的关键

所以,如果一个元组只有一个元素时,是需要加逗号的,像这样

ini 复制代码
t = (1,)

如果不加逗号,类型就不是元组了。

具名元组

使用元组存放数据,给我们带来的不便就是,不容易知道值代表的是啥,所以具名元组就出现了。

具名元组,允许为元组的每个成员命名,方便通过名称来访问,像这样

ini 复制代码
import collections
​
Point = collections.namedtuple('Point', ['x', 'y'])
p = Point(11, y=22)
print(p.x, p.y) # 输出结果:11 22

当然这是通用的方法,如果在高版本(3.6以后),还可以使用typing模块来定义具名数组类型,像这样

python 复制代码
from typing import NamedTuple
​
​
class Point(NamedTuple):
    x: int
    y: int
p = Point(11, 22)
print(p.x, p.y) # 输出结果:11 22

这种写法,看着可读性更强。

字典

使用键值访问字典内容时,为了防止出现,键不存在导致报错KeyError,我们通常会增加判断,像这样

bash 复制代码
dic = {"name": "panda", "age": 18}
if 'sex' in dic:
    print(dic['sex'])
else:
    print('sex not in dic')

当然还有另外一种写法,像这样

python 复制代码
dic = {"name": "panda", "age": 18}
try:
    print(dic['sex'])
except KeyError:
    print('sex not in dic')

看着这种写法更加简洁。

如果访问键不存在时,给一个默认值,可以使用get方法,像这样

bash 复制代码
dic = {"name": "panda", "age": 18}
print(dic.get("sex", "男")) # 男

现在,有这样一个需求,给定一个列表,将列表中的值作为字典的键,值默认为空列表,我们是这样实现的

ini 复制代码
dic = {}
words = ['apple', 'banana', 'orange', 'pear', 'peach']
for word in words:
    dic[word] = []

但我们如果使用collections.defaultdict就会简洁很多,像这样

ini 复制代码
import collections
dic = collections.defaultdict(list)

这行代码创建了一个defaultdict对象,其中list是指定的默认值类型。

删除键,如果键不存在,我们需要增加判断,像这样

python 复制代码
dic = {"name": "panda", "age": 18}
try:
    del dic['sex']
except KeyError:
    print('sex not in dic')

当然也可以使用pop方法,像这样

ini 复制代码
dic = {"name": "panda", "age": 18}
dic.pop("sex", None)

调用pop方法时传入默认值None,这样键不存在也不会出现异常。当然pop最大的作用是用来取删除键对应的值。

有序 or 无序

之前我都觉得:字典是无序的,其实在Python3.6以后字典变得有序了。当然collections.OrderedDict也可以保证字典的有序性。

注意:只有可哈希对象才可以作为字典的键

集合

我们都知道集合是一种无序的可变容器类型,特点就是不能重复。

我们可以使用add方法添加集合元素,像这样

ini 复制代码
set_ = {1, 2, 3}
set_.add(4)
print(set_) # {1, 2, 3, 4}

如果我们想要一个不可变的集合,可以使用内置类型frozenset,像这样

scss 复制代码
set_ = frozenset([1, 2, 3])
set_.add(4) # AttributeError: 'frozenset' object has no attribute 'add'

集合,求交集、并集、差集,像这样

scss 复制代码
set_1 = set([1, 2, 3, 5])
set_2 = set([1, 2, 3, 4])
​
print(set_1 & set_2) # {1, 2, 3}
print(set_1 | set_2) # {1, 2, 3, 4, 5}
print(set_1 - set_2) # {5} 前一个集合有后一个集合没有

当然也可以使用方法实现,像这样

scss 复制代码
set_1 = set([1, 2, 3, 5])
set_2 = set([1, 2, 3, 4])
​
​
print(set_1.intersection(set_2)) # 交集
print(set_1.union(set_2)) # 并集
print(set_1.difference(set_2)) # 差集

集合只能存放可哈希对象,像这样

ini 复制代码
set_1 = {[1, 2, 3, 5]}
print(set_1) # TypeError: unhashable type: 'list'

提示我们列表是不可哈希的,判断是不是可哈希可以使用hash()。可变的内置类都是不可哈希的,比如字典、列表,当然可哈希的不一定永远可哈希,比如不可变容器类型元组,原本是可哈希的,如果元素包含列表,就变为了不可哈希,像这样

ini 复制代码
tup = (1, 2, 3, 5)
print(hash(tup)) # 7098540143285066217
​
tup_new = ([1, 2], 3, 5)
print(hash(tup_new)) # TypeError: unhashable type: 'list'

注意:用户自己定义的对象,默认都是可哈希的

最后

Python好入门,但想要更上一层,还需要基础更扎实一些。

相关推荐
2601_967987376 分钟前
如何运行 Python 代码
python·最佳实践·脚本文件·代码运行·交互式环境
WiKiLeaks_successor7 分钟前
重构Time库的抽象设计
python·重构
AI源码16 分钟前
基于 Python 的短视频用户行为分析系统
开发语言·python
IT规划师23 分钟前
编程术语中的同步与异步:从"等不等"到工程取舍
后端·面试
第九序言T28 分钟前
数据分析岗 Pandas 面试题 20 道(上):概念与读代码
python·数据分析·pandas·数据处理
Dmz丶30 分钟前
前端转 AI 100 天 Day 37:Few-shot 与 CoT——让模型学会“推理”
python
孟健1 小时前
我用Grok Bot本地剪口播视频,3段提示词搞定气口切除、字幕与封面
人工智能·python·aigc
孟陬1 小时前
Foobar 技术周刊#159:当看不懂代码时,如何高效排障调试。脏页陷阱:一条只读查询,写入数 TB 数据。推测解码:大模型加速利器
前端·人工智能·后端
GoGeekBaird1 小时前
别再给每个 AI 做自我介绍了:我做了一个「个人上下文」管理系统
后端·github·agent
2601_966949651 小时前
如何封装 qd.klines.batch(),让批量 K 线查询函数在多个策略中复用?
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash