我可以提供一些简单的例子,说明何时使用冷冻装置是帮助我更好地理解这个概念的最佳选择。
答案 0 :(得分:11)
frozenset()
个对象可以用作字典键,也可以用作set()
和frozenset()
个对象的 值,其中set
个对象不能。 set()
值是可变的且不可清除,frozenset()
值是不可变的并且是可清除的。
它们是set
个对象tuple
对象与list
个对象的对象。
演示:
>>> s = set([1, 2])
>>> fs = frozenset(s)
>>> adict = {}
>>> adict[s] = 42 # a set as key does not work
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> adict[fs] = 42 # a frozenset as key works
>>> s.add(s) # a set as value in a set does not work
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> s.add(fs) # a frozenset as value in a set works
最近的Python版本将优化set literal的使用:
if somevar in {'foo', 'bar', 'baz'}:
通过使用字节码存储frozenset()
常量:
>>> import dis
>>> dis.dis(compile("if somevar in {'foo', 'bar', 'baz'}: pass", '<stdin>', 'exec'))
1 0 LOAD_NAME 0 (somevar)
3 LOAD_CONST 4 (frozenset({'foo', 'baz', 'bar'}))
6 COMPARE_OP 6 (in)
9 POP_JUMP_IF_FALSE 15
12 JUMP_FORWARD 0 (to 15)
>> 15 LOAD_CONST 3 (None)
18 RETURN_VALUE
因为无论如何都无法突变; 这使得使用集合来测试非常有效。常规set()
不能以这种方式存储,因为这样可以改变存储在字节对象中的常量。
答案 1 :(得分:2)
为了赞美Martijn所说的,我经常将它们用于缓存键。例如,一个memoize装饰器,可以关闭(args, frozenset(kwargs.items())
。