概述
Python核心类型总结
Python内置的核心数据类型如下表所示。
对象类型 | 分类 | 是否可变 |
---|---|---|
数字 | 数值 | 否 |
字符串 | 序列 | 否 |
元组 | 序列 | 否 |
列表 | 序列 | 是 |
集合 | 集合 | 是 |
字典 | 映射 | 是 |
在使用的时候,需要我们注意的是python中的一切变量都是引用赋值的。变量本身没有数据类型,有数据类型的是对象。变量就是一个void *
类型的指针。
- 列表,元组,字典可以包含任何种类的对象,可以任意嵌套。
- 集合只能包含不可变类型的对象
因为Python中的复合对象类型可以嵌套任意的对象类型,因此它们几乎可以表示任意的复杂数据。
嵌套对象在内部实际上被表示为指向不同内存区域的指针。
引用和复制
通常情况下,变量的引用赋值是符合我们预期的。如果你确实需要复制对象,那么可以使用下面的方法来实现。
浅拷贝
浅拷贝是指只对顶层进行复制操作,嵌套在内部的数据结构不会被复制。
- 不带有任何参数的分片,例如:
>>> l = [1, 2, 3]
>>> l2=l[:] # 复制
>>> l3=l[::] # 复制
>>> l4=l # 引用
>>> id(l)
138078511943584
>>> id(l2)
138078511943344
>>> id(l3)
138078511943184
>>> id(l4)
138078511943584
可以看到l和l4的id值是相同的,而使用不带有任何参数的分片进行赋值操作,结果是复制。因此l2和l3的id值是新的,和l不相同。
-
字典,集合,列表拥有的copy()方法
例如newX = X.copy(),这样就完成了把X复制到newX的操作。
-
使用构造函数进行复制
内置类型实际上也都是类,可以使用它们构造函数完成复制操作。例如:list(l),dict(d),set(s)
深拷贝
不仅仅复制顶层,也会复制嵌套的数据结构。这将是完整的,完全的独立的复制。可以使用标准库的copy模块来做到深拷贝。
>>> import copy
>>> L1 = [1,2, [1,2]]
>>> L2 = copy.deepcopy(L1)
>>> L2
[1, 2, [1, 2]]
>>> id(L1[-1])
130018979552256
>>> id(L2[-1])
130018978665408
可以看到,使用copy.deepcopy()方法复制对象,会将嵌套的数据结构也进行复制。
深拷贝是极少出现的情况,如果你需要使用深拷贝,必须要慎重考虑。
比较
比较也是非常重要的一部分内容。因为对于不同分类而言,比较的方式是不同的。
-
数值比较会将比较的对象转换成必要的最高级类型之后,比较数值的相对大小。
-
字符串比较按照ord()函数返回的字符集编码顺序进行比较,比较是从头至尾一个字符接一个字符地进行比较,直到发现第一处区别或者直至末尾。
-
列表和元组从左到右对每个元素的内容进行比较,并且会对嵌套的结构进行递归对比,直至末尾或发现第一处区别。
-
集合的比较是采取子集和超集的方式,如果A和B两个集合互为子集,那么它们就是相等的。
-
在python3中,字典只支持==和!=检查,不支持相对大小比较。在python2是支持的比较的,比较的是排序之后的(key, value)列表。
-
混合类型比较,在python3中,不支持混合类型比较(数值类型除外,可以比较:1 < 1.2, 但是不能比较1 < (2 + 3j)),例如:12 < “12”,会引发类型异常。
>>> 1 < 1.2 True >>> 1 < (1+2j) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: '<' not supported between instances of 'int' and 'complex' >>>
深拷贝和比较
下面是一个例子,其中的a列表包含了它自己的引用。
>>> a = [1]
>>> a.append(a)
>>> a
[1, [...]]
>>> b = copy.deepcopy(a) # 深拷贝a
>>> b
[1, [...]]
>>> a == b # 对比a和b
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RecursionError: maximum recursion depth exceeded in comparison
>>>
我们深拷贝了a,但是并没有触发堆栈溢出,这是因为深度拷贝函数 deepcopy 中会维护一个字典,记录已经拷贝的对象与其 ID。拷贝过程中,如果字典里已经存储了将要拷贝的对象,则会从字典直接返回。
# python3.8中的deepcopy源码
def deepcopy(x, memo=None, _nil=[]):
"""Deep copy operation on arbitrary Python objects.
See the module's __doc__ string for more info.
"""
if memo is None:
memo = {} # 空字典
d = id(x) # 查询x的id
y = memo.get(d, _nil) # 查询字典中是否存在id
if y is not _nil: # 如果存在这个id,直接返回对应的值
return y
cls = type(x)
copier = _deepcopy_dispatch.get(cls)
if copier is not None:
y = copier(x, memo)
else:
if issubclass(cls, type):
y = _deepcopy_atomic(x, memo)
else:
copier = getattr(x, "__deepcopy__", None)
if copier is not None:
y = copier(memo)
else:
reductor = dispatch_table.get(cls)
if reductor:
rv = reductor(x)
else:
reductor = getattr(x, "__reduce_ex__", None)
if reductor is not None:
rv = reductor(4)
else:
reductor = getattr(x, "__reduce__", None)
if reductor:
rv = reductor()
else:
raise Error(
"un(deep)copyable object of type %s" % cls)
if isinstance(rv, str):
y = x
else:
y = _reconstruct(x, memo, *rv)
# If is its own copy, don't memoize.
if y is not x:
memo[d] = y
_keep_alive(x, memo) # Make sure x lives at least as long as d
return y
在执行 == 操作时,因为a中存储了自身的引用,会无限的递归与b比较,从而造成RecursionError异常,因为最大递归深度有一定的限制。
最后
以上就是开朗斑马为你收集整理的Python核心类型总结Python核心类型总结的全部内容,希望文章能够帮你解决Python核心类型总结Python核心类型总结所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复