Python 使对象不可变
我有一个Python 使对象不可变,python,Python,我有一个defaultdict(list),我想使它不可变,这样我就可以将这种类型的对象添加到集合中。我有一个如何使其不可变的想法,但这需要我编写几行代码。在python中没有更简单的实现方法吗 在python中,当解析一段数据时,在解析完成后冻结它之前填充(例如,defaultdict(list))不是很常见吗 对象也可以是tuple类型,但不能用作dict键,例如: >>> a = ([1,2],[2,3]) >>> type(a) <type 't
defaultdict(list)
,我想使它不可变,这样我就可以将这种类型的对象添加到集合中。我有一个如何使其不可变的想法,但这需要我编写几行代码。在python中没有更简单的实现方法吗
在python中,当解析一段数据时,在解析完成后冻结它之前填充(例如,defaultdict(list)
)不是很常见吗
对象也可以是tuple类型,但不能用作dict键,例如:
>>> a = ([1,2],[2,3])
>>> type(a)
<type 'tuple'>
>>> d = dict()
>>> d[a] = 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>a=([1,2],[2,3])
>>>类型(a)
>>>d=dict()
>>>d[a]=1
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:不可损坏的类型:“列表”
我也不明白为什么python中存在一个列表元组。要使可变对象不可变,必须将其所有可变容器替换为其不可变的对应对象。一个所有值本身都是不可变的字典可以简单地设置为不可变 从以下方面改编示例:
因此,我建议在这种情况下使用defaultdict(tuple)而不是defaultdict(list),并且冻结、解包、排序并转换为一个tuple 另一种解决方案是使用耐热包装。Pyristent是一些持久性集合(有些称为功能数据结构)。在某种意义上说,它们是不可变的 我建议使用冻结 一个最小工作示例(MWE):
请看:另外:“以及价值观”也不是真的。元组不阻止其项的更改。试着把可变的东西放在那里,这就是我的观点。阅读答案的开头部分“要使可变对象不可变,其所有可变容器必须替换为其不可变的对应对象”。在这个人为的示例中,所讨论的元组只包含整数,因此“此defaultdict(元组)中的值是不可变的”
import collections as coll
s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
d = coll.defaultdict(tuple)
for k, v in s:
d[k] = d[k] + (v,)
print(d)
# prints
defaultdict(<class 'tuple'>, {'yellow': (1, 3), 'blue': (2, 4), 'red': (1,)})
def dict_freeze(d):
# This is the trivial one-line function
# It assumes the values are of immutable types, i.e. no lists.
# It unpacks dict items, sorts and converts to tuple
# sorting isn't strictly necessary, but dictionaries don't preserve order
# thus we could end up with the following:
# d = {'a': 1, 'b': 2} could get frozen as either of the following
# (('a', 1), ('b', 2)) != (('b', 2), ('a', 1))
return tuple(sorted(d.items()))
frozen_d = dict_freeze(d)
print(frozen_d)
# prints
(('blue', (2, 4)), ('red', (1,)), ('yellow', (1, 3)))
from pyrsistent import freeze
d = {"a":1, "b": 2}
d = freeze(d) # immutable dictionary
print(d)
## pmap({'b': 2, 'a': 1})
# Try to change a key-value
d["b"] = 10
## TypeError: 'PMap' object does not support item assignment
# If you want to change a blue you need to create a new object using "update"
d.update({"b":10})
## pmap({'b': 10, 'a': 1})